atom complier user’s guide - valmetepsservices.valmet.com/support/archive/doclibrary/... ·...

69
Atom Complier User’s Guide 278717 Rev. A1

Upload: others

Post on 17-Mar-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Complier Userrsquos Guide

278717 Rev A1

Metso Automation bull 278717 bull

Refer to this publication for complete and accurate information that helps you better operate and service Metso Automation equipment Your comments and suggestions are welcome

Metso 1180 Church Road Lansdale PA 19446 Attention Manager Technical Publications

Copyright 2010 by Metso Automation USA Inc Printed in the United States of America

All rights reserved

Metso Automation bull 278717 bull

Contents

CHAPTER 1 1-1

Introduction 1-1 What is the Atom Compiler 1-1 Overview of a Custom Function Block 1-2 Workstation and DPU Versions 1-3 Using the Compiler A Simple Example 1-3 Changing the Shell Variables 1-13 Help 1-14 Files 1-15 Compiler Errors 1-15 Summary 1-16

CHAPTER 2 2-1

Variables and Constants and Data Types Oh my 2-1 Overview 2-1 Variables 2-1

Rules for Naming Variables 2-1 Public and Private Variables 2-2

Constants 2-3 Rules for Naming Constants 2-4 Public Constants 2-4 Predefined Constants 2-4

Data Types 2-4 Allowable Data Types for Variables 2-5 Allowable Data Types for Constants 2-5

Declaring Variables and Constants 2-5 Declaring Variables 2-5 Declaring Constants 2-7 Number Bases 2-8

Special Variables 2-9 Abstime 2-9 Elapsed 2-9 Failover 2-10 FirstPass 2-10 FBAddr 2-10 FBCh 2-10 FBDevice 2-11 FBSubCh 2-11 FBSubSubCh 2-11 Gname 2-11 HID 2-11

Metso Automation bull 278717bull iv

RelTime 2-11 Tagname 2-11 Value 2-11

Type Statement 2-11 Overview 2-11 Syntax 2-12 An Example 2-13 Caution 2-14

CHAPTER 3 3-1

Say it with Expression 3-1 Overview 3-1 Operators 3-1

Arithmetic Operators 3-2 Logical Operators3-2 Comparison Operators 3-3 String Operators 3-3 Order Operators 3-3

CHAPTER 4 4-1

Built-in Functions 4-1 An Abundance of Functions 4-1

Trigonometric Functions 4-1 Mathematical Functions 4-2 String Functions 4-2 Quality Functions 4-3 Communications Functions 4-4 Shell Functions 4-6

CHAPTER 5 5-1

Subroutines amp User-Defined Functions 5-1 Overview 5-1 Syntax for Subroutines 5-2 Syntax for User-defined Functions5-3

CHAPTER 6 6-1

Executable Statements 6-1 Overview 6-1 Let 6-1 IF 6-1 With 6-3

CHAPTER 7 7-1

Therersquos a Method to the Madness 7-1 Overview 7-1 Read Method 7-2

Write Method 7-2 Check Method 7-4

CHAPTER 8 8-1

Things to Make Your Programming Life Easier 8-1 Overview 8-1 Program Template 8-1 Reusing Custom Compiled Function Blocks 8-2 Preserve Your Program Source 8-2

CHAPTER 9 9-1

Putting it all Together 9-1 Overview 9-1 Sensor Failure Detector 9-1 Using the Sensor Failure Detector in Your Own Configuration 9-3

Metso Automation bull 278717 bull

Chapter 1

Introduction

What is the Atom Compiler The basic functional block that runs in a maxDPU4F is called an atom Each atom provides essential logical arithmetic or control functions When these functional blocks are interconnected in the DPUrsquos database they provide monitoring and control functions for the userrsquos process Metso Automation provides a large number of standard functional blocks (atoms) that provide functions such as logical ANDOR mathematical addition counting timing PID control etc These functional blocks may be combined into groups for easy reuse

Sometimes the standard functional blocks do not provide the exact functionality that a user desires In that case it is better for the user to create his or her own special function block ndash one that better provides the function that the user wants Frequently that is done by simply combining existing functions into one new group and bringing the important inputoutput signals outside the block These are called custom function blocks

Sometimes though it is even better to create an entirely new function by writing a computer program that gives you exactly the functionality that you desire The Atom Compiler is a tool that permits the user to create his or her own custom atom for a maxDPU4F These custom compiled function blocks may be reused as desired just as the standard blocks and other custom blocks are reused

Thus the compiled function block is a special type of custom function block It distinguishes itself from other custom blocks in that it is created by the user writing a program to perform a new function instead of performing a new function by only combining pre-existing functions

The custom compiled function block is created by means of a simple programming language The Atom Compiler is the tool that converts the userrsquos program into a form that the DPU understands

As an example of the need for the Atom Compiler consider the DPUrsquos support of non-Metso Automation communications protocols such as Profibus In order for a DPU to access the field device data embedded in a Profibus message it needs to be able to encode and decode the message on a

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-2

bit by bit basis It must process each message in a different way depending upon the values of the header bits in each message

While it might be possible to perform the message processing functions by combining large numbers of standard function blocks it would not be an easy task It would also be somewhat difficult to maintain Furthermore due to the large number of blocks it might not run fast enough to support the required communications rate

However with the use of the Atom Compiler the user can create a single function block that is able to process the message The compiled function block is easier to maintain since all of the logic is contained within one easy to read text file Since all of the logic is contained within one atom it will run quickly and its timing may be easily changed by simply assigning it to one of the three Service Time Classes as with any other function block

Overview of a Custom Function Block Obviously a function block would be useless if it did not have a set of inputs and outputs to connect it to your process and to other function blocks The inputs and outputs are called Shell Variables They are the only function block signals that may be accessed by the system All other signals are internal signals and are hidden from view

The user defines the Shell Variables for his custom function block by means of maxDPUTools

Then the user uses the Atom Compiler to write the program that defines the function to be performed by the block The program uses the Shell Variables to communicate with the outside world

Once the Custom Function has been created the only thing left to do is to use it in your configuration That is done exactly as you would any standard function block

In maxDPUTools right click on a group and select ldquoAdd Blockrdquo Scroll through the list of function blocks and click on your custom function Add it to the DPUrsquos configuration connect the Shell Variables (inputs and outputs) download the configuration to the DPU and you are done

User-Defined Function

(Program)

Shell Variables (Inputs)

Shell Variables (Outputs)

Figure 1 ndash Block Diagram of a Custom Function Block

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 2: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Refer to this publication for complete and accurate information that helps you better operate and service Metso Automation equipment Your comments and suggestions are welcome

Metso 1180 Church Road Lansdale PA 19446 Attention Manager Technical Publications

Copyright 2010 by Metso Automation USA Inc Printed in the United States of America

All rights reserved

Metso Automation bull 278717 bull

Contents

CHAPTER 1 1-1

Introduction 1-1 What is the Atom Compiler 1-1 Overview of a Custom Function Block 1-2 Workstation and DPU Versions 1-3 Using the Compiler A Simple Example 1-3 Changing the Shell Variables 1-13 Help 1-14 Files 1-15 Compiler Errors 1-15 Summary 1-16

CHAPTER 2 2-1

Variables and Constants and Data Types Oh my 2-1 Overview 2-1 Variables 2-1

Rules for Naming Variables 2-1 Public and Private Variables 2-2

Constants 2-3 Rules for Naming Constants 2-4 Public Constants 2-4 Predefined Constants 2-4

Data Types 2-4 Allowable Data Types for Variables 2-5 Allowable Data Types for Constants 2-5

Declaring Variables and Constants 2-5 Declaring Variables 2-5 Declaring Constants 2-7 Number Bases 2-8

Special Variables 2-9 Abstime 2-9 Elapsed 2-9 Failover 2-10 FirstPass 2-10 FBAddr 2-10 FBCh 2-10 FBDevice 2-11 FBSubCh 2-11 FBSubSubCh 2-11 Gname 2-11 HID 2-11

Metso Automation bull 278717bull iv

RelTime 2-11 Tagname 2-11 Value 2-11

Type Statement 2-11 Overview 2-11 Syntax 2-12 An Example 2-13 Caution 2-14

CHAPTER 3 3-1

Say it with Expression 3-1 Overview 3-1 Operators 3-1

Arithmetic Operators 3-2 Logical Operators3-2 Comparison Operators 3-3 String Operators 3-3 Order Operators 3-3

CHAPTER 4 4-1

Built-in Functions 4-1 An Abundance of Functions 4-1

Trigonometric Functions 4-1 Mathematical Functions 4-2 String Functions 4-2 Quality Functions 4-3 Communications Functions 4-4 Shell Functions 4-6

CHAPTER 5 5-1

Subroutines amp User-Defined Functions 5-1 Overview 5-1 Syntax for Subroutines 5-2 Syntax for User-defined Functions5-3

CHAPTER 6 6-1

Executable Statements 6-1 Overview 6-1 Let 6-1 IF 6-1 With 6-3

CHAPTER 7 7-1

Therersquos a Method to the Madness 7-1 Overview 7-1 Read Method 7-2

Write Method 7-2 Check Method 7-4

CHAPTER 8 8-1

Things to Make Your Programming Life Easier 8-1 Overview 8-1 Program Template 8-1 Reusing Custom Compiled Function Blocks 8-2 Preserve Your Program Source 8-2

CHAPTER 9 9-1

Putting it all Together 9-1 Overview 9-1 Sensor Failure Detector 9-1 Using the Sensor Failure Detector in Your Own Configuration 9-3

Metso Automation bull 278717 bull

Chapter 1

Introduction

What is the Atom Compiler The basic functional block that runs in a maxDPU4F is called an atom Each atom provides essential logical arithmetic or control functions When these functional blocks are interconnected in the DPUrsquos database they provide monitoring and control functions for the userrsquos process Metso Automation provides a large number of standard functional blocks (atoms) that provide functions such as logical ANDOR mathematical addition counting timing PID control etc These functional blocks may be combined into groups for easy reuse

Sometimes the standard functional blocks do not provide the exact functionality that a user desires In that case it is better for the user to create his or her own special function block ndash one that better provides the function that the user wants Frequently that is done by simply combining existing functions into one new group and bringing the important inputoutput signals outside the block These are called custom function blocks

Sometimes though it is even better to create an entirely new function by writing a computer program that gives you exactly the functionality that you desire The Atom Compiler is a tool that permits the user to create his or her own custom atom for a maxDPU4F These custom compiled function blocks may be reused as desired just as the standard blocks and other custom blocks are reused

Thus the compiled function block is a special type of custom function block It distinguishes itself from other custom blocks in that it is created by the user writing a program to perform a new function instead of performing a new function by only combining pre-existing functions

The custom compiled function block is created by means of a simple programming language The Atom Compiler is the tool that converts the userrsquos program into a form that the DPU understands

As an example of the need for the Atom Compiler consider the DPUrsquos support of non-Metso Automation communications protocols such as Profibus In order for a DPU to access the field device data embedded in a Profibus message it needs to be able to encode and decode the message on a

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-2

bit by bit basis It must process each message in a different way depending upon the values of the header bits in each message

While it might be possible to perform the message processing functions by combining large numbers of standard function blocks it would not be an easy task It would also be somewhat difficult to maintain Furthermore due to the large number of blocks it might not run fast enough to support the required communications rate

However with the use of the Atom Compiler the user can create a single function block that is able to process the message The compiled function block is easier to maintain since all of the logic is contained within one easy to read text file Since all of the logic is contained within one atom it will run quickly and its timing may be easily changed by simply assigning it to one of the three Service Time Classes as with any other function block

Overview of a Custom Function Block Obviously a function block would be useless if it did not have a set of inputs and outputs to connect it to your process and to other function blocks The inputs and outputs are called Shell Variables They are the only function block signals that may be accessed by the system All other signals are internal signals and are hidden from view

The user defines the Shell Variables for his custom function block by means of maxDPUTools

Then the user uses the Atom Compiler to write the program that defines the function to be performed by the block The program uses the Shell Variables to communicate with the outside world

Once the Custom Function has been created the only thing left to do is to use it in your configuration That is done exactly as you would any standard function block

In maxDPUTools right click on a group and select ldquoAdd Blockrdquo Scroll through the list of function blocks and click on your custom function Add it to the DPUrsquos configuration connect the Shell Variables (inputs and outputs) download the configuration to the DPU and you are done

User-Defined Function

(Program)

Shell Variables (Inputs)

Shell Variables (Outputs)

Figure 1 ndash Block Diagram of a Custom Function Block

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 3: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Contents

CHAPTER 1 1-1

Introduction 1-1 What is the Atom Compiler 1-1 Overview of a Custom Function Block 1-2 Workstation and DPU Versions 1-3 Using the Compiler A Simple Example 1-3 Changing the Shell Variables 1-13 Help 1-14 Files 1-15 Compiler Errors 1-15 Summary 1-16

CHAPTER 2 2-1

Variables and Constants and Data Types Oh my 2-1 Overview 2-1 Variables 2-1

Rules for Naming Variables 2-1 Public and Private Variables 2-2

Constants 2-3 Rules for Naming Constants 2-4 Public Constants 2-4 Predefined Constants 2-4

Data Types 2-4 Allowable Data Types for Variables 2-5 Allowable Data Types for Constants 2-5

Declaring Variables and Constants 2-5 Declaring Variables 2-5 Declaring Constants 2-7 Number Bases 2-8

Special Variables 2-9 Abstime 2-9 Elapsed 2-9 Failover 2-10 FirstPass 2-10 FBAddr 2-10 FBCh 2-10 FBDevice 2-11 FBSubCh 2-11 FBSubSubCh 2-11 Gname 2-11 HID 2-11

Metso Automation bull 278717bull iv

RelTime 2-11 Tagname 2-11 Value 2-11

Type Statement 2-11 Overview 2-11 Syntax 2-12 An Example 2-13 Caution 2-14

CHAPTER 3 3-1

Say it with Expression 3-1 Overview 3-1 Operators 3-1

Arithmetic Operators 3-2 Logical Operators3-2 Comparison Operators 3-3 String Operators 3-3 Order Operators 3-3

CHAPTER 4 4-1

Built-in Functions 4-1 An Abundance of Functions 4-1

Trigonometric Functions 4-1 Mathematical Functions 4-2 String Functions 4-2 Quality Functions 4-3 Communications Functions 4-4 Shell Functions 4-6

CHAPTER 5 5-1

Subroutines amp User-Defined Functions 5-1 Overview 5-1 Syntax for Subroutines 5-2 Syntax for User-defined Functions5-3

CHAPTER 6 6-1

Executable Statements 6-1 Overview 6-1 Let 6-1 IF 6-1 With 6-3

CHAPTER 7 7-1

Therersquos a Method to the Madness 7-1 Overview 7-1 Read Method 7-2

Write Method 7-2 Check Method 7-4

CHAPTER 8 8-1

Things to Make Your Programming Life Easier 8-1 Overview 8-1 Program Template 8-1 Reusing Custom Compiled Function Blocks 8-2 Preserve Your Program Source 8-2

CHAPTER 9 9-1

Putting it all Together 9-1 Overview 9-1 Sensor Failure Detector 9-1 Using the Sensor Failure Detector in Your Own Configuration 9-3

Metso Automation bull 278717 bull

Chapter 1

Introduction

What is the Atom Compiler The basic functional block that runs in a maxDPU4F is called an atom Each atom provides essential logical arithmetic or control functions When these functional blocks are interconnected in the DPUrsquos database they provide monitoring and control functions for the userrsquos process Metso Automation provides a large number of standard functional blocks (atoms) that provide functions such as logical ANDOR mathematical addition counting timing PID control etc These functional blocks may be combined into groups for easy reuse

Sometimes the standard functional blocks do not provide the exact functionality that a user desires In that case it is better for the user to create his or her own special function block ndash one that better provides the function that the user wants Frequently that is done by simply combining existing functions into one new group and bringing the important inputoutput signals outside the block These are called custom function blocks

Sometimes though it is even better to create an entirely new function by writing a computer program that gives you exactly the functionality that you desire The Atom Compiler is a tool that permits the user to create his or her own custom atom for a maxDPU4F These custom compiled function blocks may be reused as desired just as the standard blocks and other custom blocks are reused

Thus the compiled function block is a special type of custom function block It distinguishes itself from other custom blocks in that it is created by the user writing a program to perform a new function instead of performing a new function by only combining pre-existing functions

The custom compiled function block is created by means of a simple programming language The Atom Compiler is the tool that converts the userrsquos program into a form that the DPU understands

As an example of the need for the Atom Compiler consider the DPUrsquos support of non-Metso Automation communications protocols such as Profibus In order for a DPU to access the field device data embedded in a Profibus message it needs to be able to encode and decode the message on a

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-2

bit by bit basis It must process each message in a different way depending upon the values of the header bits in each message

While it might be possible to perform the message processing functions by combining large numbers of standard function blocks it would not be an easy task It would also be somewhat difficult to maintain Furthermore due to the large number of blocks it might not run fast enough to support the required communications rate

However with the use of the Atom Compiler the user can create a single function block that is able to process the message The compiled function block is easier to maintain since all of the logic is contained within one easy to read text file Since all of the logic is contained within one atom it will run quickly and its timing may be easily changed by simply assigning it to one of the three Service Time Classes as with any other function block

Overview of a Custom Function Block Obviously a function block would be useless if it did not have a set of inputs and outputs to connect it to your process and to other function blocks The inputs and outputs are called Shell Variables They are the only function block signals that may be accessed by the system All other signals are internal signals and are hidden from view

The user defines the Shell Variables for his custom function block by means of maxDPUTools

Then the user uses the Atom Compiler to write the program that defines the function to be performed by the block The program uses the Shell Variables to communicate with the outside world

Once the Custom Function has been created the only thing left to do is to use it in your configuration That is done exactly as you would any standard function block

In maxDPUTools right click on a group and select ldquoAdd Blockrdquo Scroll through the list of function blocks and click on your custom function Add it to the DPUrsquos configuration connect the Shell Variables (inputs and outputs) download the configuration to the DPU and you are done

User-Defined Function

(Program)

Shell Variables (Inputs)

Shell Variables (Outputs)

Figure 1 ndash Block Diagram of a Custom Function Block

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 4: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717bull iv

RelTime 2-11 Tagname 2-11 Value 2-11

Type Statement 2-11 Overview 2-11 Syntax 2-12 An Example 2-13 Caution 2-14

CHAPTER 3 3-1

Say it with Expression 3-1 Overview 3-1 Operators 3-1

Arithmetic Operators 3-2 Logical Operators3-2 Comparison Operators 3-3 String Operators 3-3 Order Operators 3-3

CHAPTER 4 4-1

Built-in Functions 4-1 An Abundance of Functions 4-1

Trigonometric Functions 4-1 Mathematical Functions 4-2 String Functions 4-2 Quality Functions 4-3 Communications Functions 4-4 Shell Functions 4-6

CHAPTER 5 5-1

Subroutines amp User-Defined Functions 5-1 Overview 5-1 Syntax for Subroutines 5-2 Syntax for User-defined Functions5-3

CHAPTER 6 6-1

Executable Statements 6-1 Overview 6-1 Let 6-1 IF 6-1 With 6-3

CHAPTER 7 7-1

Therersquos a Method to the Madness 7-1 Overview 7-1 Read Method 7-2

Write Method 7-2 Check Method 7-4

CHAPTER 8 8-1

Things to Make Your Programming Life Easier 8-1 Overview 8-1 Program Template 8-1 Reusing Custom Compiled Function Blocks 8-2 Preserve Your Program Source 8-2

CHAPTER 9 9-1

Putting it all Together 9-1 Overview 9-1 Sensor Failure Detector 9-1 Using the Sensor Failure Detector in Your Own Configuration 9-3

Metso Automation bull 278717 bull

Chapter 1

Introduction

What is the Atom Compiler The basic functional block that runs in a maxDPU4F is called an atom Each atom provides essential logical arithmetic or control functions When these functional blocks are interconnected in the DPUrsquos database they provide monitoring and control functions for the userrsquos process Metso Automation provides a large number of standard functional blocks (atoms) that provide functions such as logical ANDOR mathematical addition counting timing PID control etc These functional blocks may be combined into groups for easy reuse

Sometimes the standard functional blocks do not provide the exact functionality that a user desires In that case it is better for the user to create his or her own special function block ndash one that better provides the function that the user wants Frequently that is done by simply combining existing functions into one new group and bringing the important inputoutput signals outside the block These are called custom function blocks

Sometimes though it is even better to create an entirely new function by writing a computer program that gives you exactly the functionality that you desire The Atom Compiler is a tool that permits the user to create his or her own custom atom for a maxDPU4F These custom compiled function blocks may be reused as desired just as the standard blocks and other custom blocks are reused

Thus the compiled function block is a special type of custom function block It distinguishes itself from other custom blocks in that it is created by the user writing a program to perform a new function instead of performing a new function by only combining pre-existing functions

The custom compiled function block is created by means of a simple programming language The Atom Compiler is the tool that converts the userrsquos program into a form that the DPU understands

As an example of the need for the Atom Compiler consider the DPUrsquos support of non-Metso Automation communications protocols such as Profibus In order for a DPU to access the field device data embedded in a Profibus message it needs to be able to encode and decode the message on a

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-2

bit by bit basis It must process each message in a different way depending upon the values of the header bits in each message

While it might be possible to perform the message processing functions by combining large numbers of standard function blocks it would not be an easy task It would also be somewhat difficult to maintain Furthermore due to the large number of blocks it might not run fast enough to support the required communications rate

However with the use of the Atom Compiler the user can create a single function block that is able to process the message The compiled function block is easier to maintain since all of the logic is contained within one easy to read text file Since all of the logic is contained within one atom it will run quickly and its timing may be easily changed by simply assigning it to one of the three Service Time Classes as with any other function block

Overview of a Custom Function Block Obviously a function block would be useless if it did not have a set of inputs and outputs to connect it to your process and to other function blocks The inputs and outputs are called Shell Variables They are the only function block signals that may be accessed by the system All other signals are internal signals and are hidden from view

The user defines the Shell Variables for his custom function block by means of maxDPUTools

Then the user uses the Atom Compiler to write the program that defines the function to be performed by the block The program uses the Shell Variables to communicate with the outside world

Once the Custom Function has been created the only thing left to do is to use it in your configuration That is done exactly as you would any standard function block

In maxDPUTools right click on a group and select ldquoAdd Blockrdquo Scroll through the list of function blocks and click on your custom function Add it to the DPUrsquos configuration connect the Shell Variables (inputs and outputs) download the configuration to the DPU and you are done

User-Defined Function

(Program)

Shell Variables (Inputs)

Shell Variables (Outputs)

Figure 1 ndash Block Diagram of a Custom Function Block

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 5: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Write Method 7-2 Check Method 7-4

CHAPTER 8 8-1

Things to Make Your Programming Life Easier 8-1 Overview 8-1 Program Template 8-1 Reusing Custom Compiled Function Blocks 8-2 Preserve Your Program Source 8-2

CHAPTER 9 9-1

Putting it all Together 9-1 Overview 9-1 Sensor Failure Detector 9-1 Using the Sensor Failure Detector in Your Own Configuration 9-3

Metso Automation bull 278717 bull

Chapter 1

Introduction

What is the Atom Compiler The basic functional block that runs in a maxDPU4F is called an atom Each atom provides essential logical arithmetic or control functions When these functional blocks are interconnected in the DPUrsquos database they provide monitoring and control functions for the userrsquos process Metso Automation provides a large number of standard functional blocks (atoms) that provide functions such as logical ANDOR mathematical addition counting timing PID control etc These functional blocks may be combined into groups for easy reuse

Sometimes the standard functional blocks do not provide the exact functionality that a user desires In that case it is better for the user to create his or her own special function block ndash one that better provides the function that the user wants Frequently that is done by simply combining existing functions into one new group and bringing the important inputoutput signals outside the block These are called custom function blocks

Sometimes though it is even better to create an entirely new function by writing a computer program that gives you exactly the functionality that you desire The Atom Compiler is a tool that permits the user to create his or her own custom atom for a maxDPU4F These custom compiled function blocks may be reused as desired just as the standard blocks and other custom blocks are reused

Thus the compiled function block is a special type of custom function block It distinguishes itself from other custom blocks in that it is created by the user writing a program to perform a new function instead of performing a new function by only combining pre-existing functions

The custom compiled function block is created by means of a simple programming language The Atom Compiler is the tool that converts the userrsquos program into a form that the DPU understands

As an example of the need for the Atom Compiler consider the DPUrsquos support of non-Metso Automation communications protocols such as Profibus In order for a DPU to access the field device data embedded in a Profibus message it needs to be able to encode and decode the message on a

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-2

bit by bit basis It must process each message in a different way depending upon the values of the header bits in each message

While it might be possible to perform the message processing functions by combining large numbers of standard function blocks it would not be an easy task It would also be somewhat difficult to maintain Furthermore due to the large number of blocks it might not run fast enough to support the required communications rate

However with the use of the Atom Compiler the user can create a single function block that is able to process the message The compiled function block is easier to maintain since all of the logic is contained within one easy to read text file Since all of the logic is contained within one atom it will run quickly and its timing may be easily changed by simply assigning it to one of the three Service Time Classes as with any other function block

Overview of a Custom Function Block Obviously a function block would be useless if it did not have a set of inputs and outputs to connect it to your process and to other function blocks The inputs and outputs are called Shell Variables They are the only function block signals that may be accessed by the system All other signals are internal signals and are hidden from view

The user defines the Shell Variables for his custom function block by means of maxDPUTools

Then the user uses the Atom Compiler to write the program that defines the function to be performed by the block The program uses the Shell Variables to communicate with the outside world

Once the Custom Function has been created the only thing left to do is to use it in your configuration That is done exactly as you would any standard function block

In maxDPUTools right click on a group and select ldquoAdd Blockrdquo Scroll through the list of function blocks and click on your custom function Add it to the DPUrsquos configuration connect the Shell Variables (inputs and outputs) download the configuration to the DPU and you are done

User-Defined Function

(Program)

Shell Variables (Inputs)

Shell Variables (Outputs)

Figure 1 ndash Block Diagram of a Custom Function Block

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 6: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 1

Introduction

What is the Atom Compiler The basic functional block that runs in a maxDPU4F is called an atom Each atom provides essential logical arithmetic or control functions When these functional blocks are interconnected in the DPUrsquos database they provide monitoring and control functions for the userrsquos process Metso Automation provides a large number of standard functional blocks (atoms) that provide functions such as logical ANDOR mathematical addition counting timing PID control etc These functional blocks may be combined into groups for easy reuse

Sometimes the standard functional blocks do not provide the exact functionality that a user desires In that case it is better for the user to create his or her own special function block ndash one that better provides the function that the user wants Frequently that is done by simply combining existing functions into one new group and bringing the important inputoutput signals outside the block These are called custom function blocks

Sometimes though it is even better to create an entirely new function by writing a computer program that gives you exactly the functionality that you desire The Atom Compiler is a tool that permits the user to create his or her own custom atom for a maxDPU4F These custom compiled function blocks may be reused as desired just as the standard blocks and other custom blocks are reused

Thus the compiled function block is a special type of custom function block It distinguishes itself from other custom blocks in that it is created by the user writing a program to perform a new function instead of performing a new function by only combining pre-existing functions

The custom compiled function block is created by means of a simple programming language The Atom Compiler is the tool that converts the userrsquos program into a form that the DPU understands

As an example of the need for the Atom Compiler consider the DPUrsquos support of non-Metso Automation communications protocols such as Profibus In order for a DPU to access the field device data embedded in a Profibus message it needs to be able to encode and decode the message on a

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-2

bit by bit basis It must process each message in a different way depending upon the values of the header bits in each message

While it might be possible to perform the message processing functions by combining large numbers of standard function blocks it would not be an easy task It would also be somewhat difficult to maintain Furthermore due to the large number of blocks it might not run fast enough to support the required communications rate

However with the use of the Atom Compiler the user can create a single function block that is able to process the message The compiled function block is easier to maintain since all of the logic is contained within one easy to read text file Since all of the logic is contained within one atom it will run quickly and its timing may be easily changed by simply assigning it to one of the three Service Time Classes as with any other function block

Overview of a Custom Function Block Obviously a function block would be useless if it did not have a set of inputs and outputs to connect it to your process and to other function blocks The inputs and outputs are called Shell Variables They are the only function block signals that may be accessed by the system All other signals are internal signals and are hidden from view

The user defines the Shell Variables for his custom function block by means of maxDPUTools

Then the user uses the Atom Compiler to write the program that defines the function to be performed by the block The program uses the Shell Variables to communicate with the outside world

Once the Custom Function has been created the only thing left to do is to use it in your configuration That is done exactly as you would any standard function block

In maxDPUTools right click on a group and select ldquoAdd Blockrdquo Scroll through the list of function blocks and click on your custom function Add it to the DPUrsquos configuration connect the Shell Variables (inputs and outputs) download the configuration to the DPU and you are done

User-Defined Function

(Program)

Shell Variables (Inputs)

Shell Variables (Outputs)

Figure 1 ndash Block Diagram of a Custom Function Block

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 7: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-2

bit by bit basis It must process each message in a different way depending upon the values of the header bits in each message

While it might be possible to perform the message processing functions by combining large numbers of standard function blocks it would not be an easy task It would also be somewhat difficult to maintain Furthermore due to the large number of blocks it might not run fast enough to support the required communications rate

However with the use of the Atom Compiler the user can create a single function block that is able to process the message The compiled function block is easier to maintain since all of the logic is contained within one easy to read text file Since all of the logic is contained within one atom it will run quickly and its timing may be easily changed by simply assigning it to one of the three Service Time Classes as with any other function block

Overview of a Custom Function Block Obviously a function block would be useless if it did not have a set of inputs and outputs to connect it to your process and to other function blocks The inputs and outputs are called Shell Variables They are the only function block signals that may be accessed by the system All other signals are internal signals and are hidden from view

The user defines the Shell Variables for his custom function block by means of maxDPUTools

Then the user uses the Atom Compiler to write the program that defines the function to be performed by the block The program uses the Shell Variables to communicate with the outside world

Once the Custom Function has been created the only thing left to do is to use it in your configuration That is done exactly as you would any standard function block

In maxDPUTools right click on a group and select ldquoAdd Blockrdquo Scroll through the list of function blocks and click on your custom function Add it to the DPUrsquos configuration connect the Shell Variables (inputs and outputs) download the configuration to the DPU and you are done

User-Defined Function

(Program)

Shell Variables (Inputs)

Shell Variables (Outputs)

Figure 1 ndash Block Diagram of a Custom Function Block

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 8: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Introduction

Metso Automation bull 278717 bull 1-3

Workstation and DPU Versions The Atom Compiler is supported in maxDNA workstation version 31 and later However not all Atom Compiler features are supported in all DPU versions Custom compiled function blocks that have been created on a version 43 workstation for example are compatible with earlier versions of the maxDPU4F as long as they only use features that existed at the time of the earlier release Information on feature support for various releases is shown below

The following restrictions apply to maxDPU4F versions prior to Release 43

For Releases 31 through 42

The third parameter of the ldquoSchedulerdquo function (indicating the address of the destination) is not available

The ldquoUnschedulerdquo function is not supported

For Releases 31 through 40

ldquoSubroutinesrdquo and ldquoFunctionsrdquo are not supported

The functions ldquoAvailablerdquo and ldquoSchedulerdquo are not supported

ldquoTyperdquo declarations and the rdquoWithrdquo statement are not supported

The ldquoInput Bufferrdquo and ldquoOutput Bufferrdquo data types are not supported

ldquoCRC16rdquo ldquoPadrdquo ldquoTrimrdquo and ldquoLengthrdquo string functions are not supported

The shell variables ldquoFBDevicerdquo ldquoFBCHrdquo FBSubCHrdquo ldquoFBSubSubCHrdquo and ldquoFBAddrrdquo are not supported

For Releases Prior to 31

The atom compiler is not supported prior to Release 31

Using the Compiler A Simple Example Perhaps the best way to understand the use of the Atom Compiler is by means of a simple example In order to keep this first example as easy as possible we will create a function to add two numbers Yes that function already exists in a standard function block However it will work well for this example

First we must name our custom function and define the variables

bull Start maxDPUTools and tell it that you wish to create a new configuration Call the configuration MyFunctions Answer ldquoNordquo

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 9: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-4

when asked if you wish to import any of the Standard Libraries We do not need them for this exercise

bull Right-click on the Custom tab and select ldquoAddhelliprdquo

bull Fill in the requested information to name and describe your custom function Click ldquoOKrdquo

bull We are now ready to define the shell variables for our custom adder

bull Since this function is designed to add two numbers we need input shell variables for the each of the two numbers to be added and an output shell variable for the result of the addition For simplicity letrsquos call the inputs ldquoInput1rdquo and ldquoInput2rdquo Letrsquos call the output ldquoResultrdquo The left hand pane of the maxDPUTools window has empty rows with columns labeled ldquoAttributerdquo ldquoCategoryrdquo ldquoData Typerdquo etc Each row is used to define one shell variable

lanjohnsja
Cross-Out
lanjohnsja
Inserted Text
right

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 10: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Introduction

Metso Automation bull 278717 bull 1-5

Letrsquos enter the information for our first input variable (Input1) The attribute column is used for the variablersquos name So enter ldquoInput1rdquo (without the quotes) into the Attribute field on the first row

bull Click in the adjacent cell (Category) and a drop down arrow will appear on the left side of the cell Click the arrow and a list of possible categories for the variable will drop down The Category field is used to define the shell variable as an input signal an output signal etc Click on ldquoInputrdquo and the field will be filled in Categories are explained further in the maxDPUTools manual

bull The next field defines the type of data that is applied to Input1 Click in the field and a drop down arrow will appear that shows a list of possible data types (floating point integer Boolean text etc) Select ldquoFloatrdquo for floating point Data Types are explained in the maxDPUTools manual

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 11: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-6

bull If you wish you may enter a Default Value in the next field That data will be used as the value for Input1 unless you override it by either typing in a different value or driving the input with another signal (ie referencing it)

bull The Reference column is just like the Reference column on a standard function block It specifies which external signal should be used to drive the input Leave it blank We can define it later when we use the function block

bull The Description field is used to add text that describes the attribute that we are defining Enter something that would be meaningful to a user such as ldquoA number to be addedrdquo This text will appear in the Point Browser and in maxDPUTools

bull Leave the Alternate Description field blank It is used for alternate language support Leave the Attribute Security Class (AttrSecClass) at its default value of ldquo5rdquo

bull Enter the information for the other two shell variables as shown below After you enter the information into the last field be sure to click in a different field That notifies the maxDPUTools to update the database Otherwise the last entry will not be written to the database

bull That completes the definition of the shell variables We can now start the Atom Compiler and create the function itself

bull In the left-hand windowpane right-click on the name of our custom function and select ldquoAtom Compilerrdquo from the popup menu that appears

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 12: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Introduction

Metso Automation bull 278717 bull 1-7

bull The Atom Compiler will start and a dialog box will appear that permits you to rename your function block andor specify a location in which it will be stored Accept the default name (the name you previously assigned to the function block) and location (the folder that contains the database) Click the ldquoOpenrdquo button

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 13: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-8

bull The Atom Compiler will open As you can see it automatically adds a couple of descriptive lines of comments to the file Comments must start with either two slash marks () a single quotation mark (lsquo) or ldquoRemrdquo (without the quotes) and they appear in green to enhance the readability of the program ldquoRemrdquo may only be the placed at the beginning of a line The other comment indicators may be placed anywhere on a line Also note that each line is automatically assigned a line number Click on line number 3 and type in your own comments Note how the text color changes from green to another color if you do not precede the comments with ldquoRemrdquo the quote or double slash symbols That is an indication that the compiler is not treating your text as a comment and it will cause errors in your program

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 14: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Introduction

Metso Automation bull 278717 bull 1-9

bull We are now ready to write the program that defines how our custom adder will work Every variable used in the program must be defined before it is used For this program we only need our three shell variables and we have already defined them If we needed any internal variables (that is variables that are only used inside the program and do not appear at the shell level) we would need to define them in the program We will cover how to define such program variables in a later chapter

bull We can view and print (to your default printer) the shell variables that we previously defined in maxDPUTools by clicking on the Shell Variables button on the compilerrsquos toolbar The button is circled in red on the picture below The button may also be identified by the tool tip that appears when you pause the cursor on the button A dialog box opens that shows the names of the attributes that we created as well as their Category and Data Type This provides a handy reference as you write your program The lower portion of the dialog box shows the name and location of the database that contains our custom atom definition as well as the name of the custom function itself For now click the Close button If you change the settings the custom function will not compile

bull Now type in the program for the custom function as shown in the following picture The actual program is really only one line long (Result = Input1 + Input2) The other lines are merely comments for other users to help them read and understand the program For a program as simple as this one the comments are not really necessary However it is a good idea to get in the habit of using

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 15: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-10

them You may have noticed that as you typed the program line the colors of the words changed Just as it color codes comment lines (green) for readability the complier also color codes keywords (blue) and operators (red) ldquoInputrdquo is a keyword (a word that has special meaning to the compiler keywords will be discussed further in another chapter) That is why ldquoInputrdquo appeared in blue until you finished typing the word (ldquoInput1rdquo or ldquoInput2rdquo) The ldquo=rdquo and ldquo+rdquo signs appear in red because they are operators (equality and addition) Also note that it is permissible to add a comment (ldquoThis is the equation for our adderrdquo) on the same line as an executable program instruction This can help a user understand the program

bull Now that the program has been entered it is time to compile it Compile means to convert the source program (what we typed) into a format that is understandable by the computer (the maxDPU4F) Compile the program by clicking the Compile icon on the toolbar If you pause your mouse cursor above the tool icons a tool tip will appear and show you the buttonrsquos function The Compile button is circled in red on the following picture

bull After the compile completes (a few seconds) a prompt appears that says the compilation was successful and asks if the database should be updated Click ldquoYesrdquo Congratulations you have just created your first custom function block

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 16: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Introduction

Metso Automation bull 278717 bull 1-11

Note that your program is automatically saved when you click the Compile button If you are typing in a long program you may wish to manually save your program as you go along Do that by either clicking the Floppy Disk icon on the toolbar or by clicking ldquoSaverdquo in the File menu

bull We are now done with the Compiler close it by clicking the ldquoXrdquo in the upper right corner or by clicking ldquoExitrdquo on the File menu When the Compiler closes you will automatically be returned to maxDPUTools

bull Now that we have created a custom adder function it is time to use it

bull When you return to the Custom tab of maxDPUTools you will see that a small logic gate symbol has appeared to the right of your function blockrsquos name That symbol indicates that the function block contains compiled logic The symbol is circled in red in the picture below

bull If you hover your cursor over the name of the custom compiled function block a tool tip will appear that contains useful information It shows the path within the database that contains the custom function the name of the function and the date and time that the source file was last changed and compiled If the same source is recompiled the data and time will remain as they were

lanjohnsja
Sticky Note
There is a feature with the tool tip of Test This allows you to step through the execution of the compiled code Need more information on how to use the tool Refer to the picture TestFunctionjpg
Jim Johnson
File Attachment
Screen print of Test window

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 17: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-12

bull Click on the DPU4F tab of maxDPUTools We want to create a group in which to place our custom function block Right click on ldquoMyFunctionsrdquo and select ldquoAdd Grouprdquo Name the group ldquoArithmeticrdquo and click ldquoAddrdquo and then ldquoExitrdquo

bull Right click on the ldquoArithmeticrdquo group and select ldquoAdd Blockrdquo From the list that appears select ldquoAdder2rdquo (the name of our custom block) Click on ldquoAddrdquo and then ldquoExitrdquo As you can see the procedure for using a custom compiled function block is exactly the same as the procedure for using a standard block Click on Adder2 in the left hand windowpane and you will see the configuration properties for our function We can see Input1 and Input2 Result does not appear as it is an output of the block You can see the output when the block is running in a DPU and you look at it with the Point Browser

bull Download the configuration to a DPU and examine the Adder2 function block with the Point Browser Enter numeric values for

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 18: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Introduction

Metso Automation bull 278717 bull 1-13

Input1 and Input2 See their sum in ldquoResultrdquo As you can see in the following picture Input1 was set to 1 and Input2 was set to 3 Their sum is 4 and it appears in the ldquoResultrdquo value field

bull In this very simple example we created a custom compiled function block and used it by itself in the DPU That is not a requirement of the custom block The custom block may be used like any other DPU function block It may be used in configurations with any mix of standard andor custom blocks

Changing the Shell Variables If you change the programrsquos shell variables you could break your program if you do not make a corresponding change to the program maxDPUTools and the Atom Compiler try to prevent this error by reminding you that a program update is required This will be illustrated by means of an exercise

Open the MyFunctions database in maxDPUTools and click on the Custom tab Change the name of shell variable ldquoInput1rdquo to ldquoInput3rdquo Click in a different field to commit the change A dialog box will appear with a warning that the atom program will need to be changed to match the shell variable change and then it will need to be recompiled

Click ldquoOKrdquo to acknowledge the message

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 19: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-14

The color of the compiled function symbol located to right of the function blockrsquos name will change to red The function blockrsquos tool tip will say that the atom object code is invalid These indications will remain as a reminder until you change the program and recompile it

Since we donrsquot really want to modify our program change the name of the shell variable back to Input1 Donrsquot forget to click in another field to commit the change Then start the Atom Compiler and press the Compile button Close the Atom Compiler

When you return to maxDPUTools the symbol will still be red since the screen has not been refreshed Click on the ldquoCustomrdquo or ldquoLocal Customrdquo folder icon to force a refresh The symbol will turn blue and the tool tip will show the date and time of the recompilation

Help

The compiler has some built-in help screens They are very concise since they are designed to serve as quick reminders of the programming syntax rather than as a tutorial on how to use the compiler

The main help screen may be accessed from within the compiler by clicking on the help button on the tool bar In the figure below the help button has been circled in red An alternate method of accessing the Help screen is by pressing the ldquoF1rdquo key on the keyboard

From the main help screen you may click on underlined links to take you to help screens on specific items The following figure shows an image of the main help screen

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 20: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Introduction

Metso Automation bull 278717 bull 1-15

Files The Atom Compiler produces two types of files Source program file names have the extension ldquoatomrdquo The ldquoalisrdquo file is a listing of the assembly language instructions produced by the compiler Alis files are not needed at all In the past they were used by Metso engineers when the compiler was being developed If you can read an alis file you are an alpha geek and will go far in the world of computers When you archive your source you only need to save the database and the Atom file

The end user does not even need the atom file When the source file was compiled it wrote all required information to the maxDPU4F database The atom file is not even needed to import the custom compiled function block into another database You will only need the atom file if you wish to modify the program of the compiled function block

The default location for the atom and alis files is the same folder that contains the maxDPU4F database

Compiler Errors It is not uncommon to make mistakes when programming (eg using a variable that you have not defined using incorrect syntax etc) Fortunately the Function Block Compiler has a built in mechanism to help you find and correct these problems

The error checks are done automatically when you press the ldquoCompilerdquo button

If all goes well the compiler displays a success message If any errors are detected the compiler marks the offending programming line with a blue arrow and highlights the line in yellow A message is displayed at the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 21: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 1-16

bottom of the screen that is the compilerrsquos attempt to tell you what the problem is

Donrsquot get discouraged if you see lots of error indicators Frequently errors have a cascading effect so that one error can cause many others So just work through the errors one at a time from top to bottom You will often see that fixing one error makes a lot of the other errors disappear

Summary maxDPU4F configurations can be built from standard function blocks custom function blocks andor custom compiled function blocks Standard functions are basic blocks that perform a variety of functions Custom blocks combine the pre-existing blocks other custom blocks andor custom compiled blocks into a larger block that performs a new function A custom compiled function block employs a user-written program to perform a new function

The procedure to create a custom compiled function block is quite simple The steps are summarized below

bull On the ldquoCustomrdquo tab in maxDPUTools add a custom block and give it a name and description

bull Enter the names of the blockrsquos shell variables and their parameters (input output data type default values etc)

bull Start the Atom Compiler and type in the program that will define the functionality of your custom block

bull Compile the function block

bull Go back into maxDPUTools and use your newly created function block as you would any other function block

The compilerrsquos programming language is simple and very readable The compiler automatically applies color-coding to the program lines to minimize user errors These features and others we have not yet used help the user to quickly produce easy to maintain programs (functions)

As we will see in future chapters the compiler is very powerful and its built-in functions will let the user easily perform sophisticated operations like bit manipulations on communications messages

In the following chapters we will explore the compiler its programming functions and features in more detail

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 22: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 2

Variables and Constants and Data Types Oh my

Overview Variables and constants are key elements in any computer program They are used to store information Data Types describe to the program the kind of information that the variable or constant represents

Variables A variable is a name that identifies a data value with a program The variable may hold the value of an input to a function or calculation an intermediate calculated value or the final output value of the function

Any given program may use many variables Each must be assigned a unique name so that the program and user may tell them apart It is strongly recommended that you assign names that clearly convey the variablersquos use in the program That will help greatly when you write the program and again later should you need to modify the program

For example in the simple adder example of chapter 1 we named the input variables ldquoInput1rdquo and ldquoInput2rdquo We named the output variable ldquoResultrdquo (Result = Input1 + Input2) Those names immediately convey to the reader the function of each of those variables If instead we had named the variables ldquoBobrdquo ldquoCarolrdquo and ldquoTedrdquo the reader would not have any clue as to what function each performed

Obviously this is not a real problem with a program as simple as Adder2 However the need for meaningful variable names quickly becomes very clear in more complex programs

Rules for Naming Variables The user has great flexibility in choosing names for variables However there are a few simple rules that must be followed These rules also apply to names for the shell variables

Variable names must

bull Contain at least one text character

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 23: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-2

bull Not contain any spaces

bull Not be longer than 16 characters

bull Not contain any special characters

o For example ldquo+rdquo is reserved to indicate addition If it were included in a variable name the compiler would be confused and try to add the value of the characters on either side of it

o Other special characters are - ^ amp = lt gt ^ lsquo You can identify the special characters as you type because they appear in a color other than black

bull Not be the same as any reserved words

o Reserved words (keywords) are words that have special meaning to the compiler For example ldquoNErdquo is used to denote a comparison test (Not Equal) of two values Thus if you tried to use it as a variable name it would confuse the compiler Other reserved words are the names of the Special Variables functions operators etc If the compiler color codes your variable name in any color but black it is not a valid variable name Note that the letters of a keyword may be included as part of a variable name In that case they stop being keywords and they just become letters For example OR is a keyword but FLOOR OR1 3OR and MY_OR are legal variable names

Variable names may

bull Contain numbers

bull Contain underscores ( _ ) and dashes ( - )

Public and Private Variables For the proper operation of a program it is sometimes required that the value of a variable be available to ldquoeveryonerdquo At other times it is desirable that other programs or portions of a program (eg subroutines) do not see the value of the variable That is the reason for defining variables in terms of their being either public or private Sometimes the names ldquoGlobalrdquo and ldquoLocalrdquo are used instead of ldquoPublicrdquo and ldquoPrivaterdquo

A Public variablersquos value is maintained from execution cycle to execution cycle of the program It is also available for use throughout the program A good example of the need for a variable to be Public would be if your program were counting the number of times something happened You would obviously want the count to be maintained as long as the program was running

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 24: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-3

Private variables do not share their values with other portions of a program Their value can only be read in the area in which the variable is used For that reason private variables are not declared in the public variable section at the beginning of the program Instead they are declared within the function or subroutine that uses them

The values of private variables are not saved between program execution cycles they are cleared (0 for numeric values null for a string value) For example if we counted to 3 with a private variable on the first pass through a program we would forget that value when the next execution cycle started and the next counting cycle would begin at zero

Private variables are useful in subroutines and user-defined functions If you use private variables within the routines you may freely reuse the routines in other programs without having to verify that you have not accidentally duplicated a variable name that was already used On the other hand if you call the subroutine twice there is no guarantee that the private variable will have the same value on the second call as it did on the first Keep this in mind when using private variables

In the case of a maxDPU4F the value of a Public variable in an active DPU is automatically transferred to the corresponding variable name in the inactive DPU

On the other hand the value of a Private variable is not shared with the inactive DPU When the inactive DPU goes active it would have to calculate the value for the private variable based upon the current input conditions

Constants Constants hold values that do not change throughout the course of the program (in other words their values are constant) Like variables constants are assigned names The rules for naming constants are the same as for naming variables

An obvious question is why do we bother defining and naming constants rather than just entering their value (eg ldquo125rdquo) directly into the equation The reason is for increased ease of understanding and maintaining the program

Consider the equation ldquoOutput = Input 3rdquo (ldquordquo indicates multiplication more on that later) In the application ldquo3rdquo might be a scaling factor used to convert a value from one measurement unit to another That is not obvious from the previous equation

Instead it would be much nicer to declare a constant called something like ldquoScaleFactorrdquo and set it equal to ldquo3rdquo in the Constants area of the program The equation would then become ldquoOutput = Input ScaleFactorrdquo If the user wished to convert to different measurement units at a later date it would be a simple matter to locate the constant and change it as needed That

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 25: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-4

becomes especially nice if that same scaling factor were used in many different equations throughout the program The value would then only need to be changed in one place instead of in each of the equations That reason alone can greatly reduce the chance of making an error in the program

Rules for Naming Constants Like variables constants are assigned names The rules for naming constants are the same as for naming variables

Public Constants Unlike variables constants are always public There are no private constants

Predefined Constants For ease of use a number of constants have been predefined These are listed below along with their value You may use the name instead of the numeric value in your programs It is not necessary to declare these predefined constants

Boolean Constants

True = 1 On = 1 False = 0 Off = 0

Quality Constants

Good = 0 Doubtful = 1 Substitute = 2 Bad = 3

Error Text

These text strings have been reserved for reporting specific types of errors Do not use them in your programs

SBP_Error SBP_E_OPERATION_DISALLOWED SBP_E_MODE_DISALLOWS_OPERATION SBP_E_VALUE_TYPE_ERROR SBP_E_VALUE_ERROR

Data Types Variables and constants can hold many different kinds of data For example a value could be an integer (eg -14) a floating-point number (eg 314) a Boolean (eg True or False) or a text string (eg ldquoThe water level is too lowrdquo)

It is required that we tell the program what kind of data we are dealing with The compiler needs that information so that it knows how many storage

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 26: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-5

locations are needed to hold the value and how to interpret the value For example a 32-bit integer takes up four consecutive byte locations in memory However a text string might take up 255 consecutive locations Without a definition of the data type the computer would be at a loss as to how many locations to read and how to interpret the value For example does the byte containing the bit pattern ldquo01001101rdquo represent the number ldquo77rdquo or does it represent the letter ldquoMrdquo

Allowable Data Types for Variables The allowable data types for variables (both public and private) are

Boolean (or Bool) ndash a binary value (1 or 0 True or False)

Integer ndash a signed 32-bit value

Single ndash a single precision floating point number (24-bit mantissa and 8-bit exponent)

Double ndash a double precision floating point number (52-bit mantissa and 12-bit exponent)

String ndash text (the length of the string must be included in the declaration)

Allowable Data Types for Constants The allowable data types for constants (both public and private) are integer single precision floating point and double precision floating point Unlike variables the distinction between these data types is not made by a keyword but rather by the manner in which the value is written

Integer ndash 32-bit signed number write (type) the value without a decimal point (eg ldquo73rdquo or ldquo-7642rdquo)

Single ndash write the value followed by an ldquoFrdquo (eg ldquo314Frdquo)

Double ndash write the value without a trailing letter (eg ldquo314rdquo)

Declaring Variables and Constants Declaring Variables Variables used in a program must be declared (defined) before they are used If you do not do this the compiler will not know what the variable is and will display an error message

It is common practice to place all variable declarations in one area near the beginning of the program This is done to make it easier for others to understand the program Comment lines are frequently used to highlight that area so that it is easier to locate it in a large program Additional comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 27: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-6

may be used to explain the use of the variables See the example below The details of the declarations will be explained later

V A R I A B L E S Communication Buffers Public in As Input Buffer 255 Public in2 As Input Buffer 255 Foreground control Public ID As Integer Public Outstanding As Boolean Public PortNeedsConfig As Boolean Public Timeout As Float An Example of Declaring Variables

Do not declare Shell Variables within the program Only declare Shell Variables in maxDPUTools

The format for declaring a variable is similar for all type of variables Use the keyword Public or Private as appropriate for your program followed by the variablersquos name The keyword ldquoAsrdquo is used to tell the compiler that the next word(s) will be the desired Data Type For some Data Types (strings and buffers) you must also specify the size of the data field

Use the following declarations as needed in your programs Substitute ldquoPrivaterdquo for ldquoPublicrdquo as needed Substitute the name you wish (without the quotes) for ldquonamerdquo

bull For a Boolean variable

o Public ldquonamerdquo As Boolean

Example Public LinkEstablished As Boolean

bull For an integer variable

o Public ldquonamerdquo As Integer

Example Public ErrorCounter As Integer

bull For a single precision floating point variable

o Public ldquonamerdquo As Single

Example Public Temperature As Single

A synonym for Single is Float (Single is preferred)

bull For a double precision floating point variable

o Public ldquonamerdquo As Double

Example Public DampingFactor As Double

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 28: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-7

bull For a text variable

o Public ldquonamerdquo As String n (substitute the length of the text string (in characters) for ldquonrdquo Text strings will be color coded as purple in the compiler

Example Private Alarm_Text As String 12

bull For a communications input buffer (more about this later) use

o Public ldquonamerdquo As Input Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public RcvdMessage As Input Buffer 100

bull For a communications output buffer (more about this later) use

o Public ldquonamerdquo As Output Buffer n (substitute the size of the buffer (in characters) for ldquonrdquo

Example Public Xmit_Msg As Output Buffer 16

If you declare a variable as a certain data type any value assigned to that type would be automatically converted (ldquocastrdquo as the programmers say) to that data type before the value is stored in the variable So for example if you declare A as an integer and assign the float value 314 to A (A = 314) the value will be converted to an integer and stored as 3

Misusing auto type casting can lead to unexpected results (for example if you were to assign a text string to a floating-point variable) Assume A is declared to be a floating point value The expression A = ldquoThe water is lowrdquo will produce a strange value for A (eg 6591e-37)

Declaring Constants Like variables constants must be declared in the program before they are used If you do not do this the compiler will not know what the constant is and will display an error message

Also like variables constants are typically declared in one section near the beginning of the program The following is an example of declaring constants The comments are employed to help the user locate the constants declaration area of the program

C O N S T A N T S Public Const MAXTimeOut = 5 serial card commands Public Const CmdConfig = 16 Public Const GetUartStats = 17 An Example of Declaring Constants

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 29: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-8

The format for declaring a constant is similar for all type of constants Use the keyword Public (there are no private constants) followed by the keyword ldquoConstrdquo and then the constantrsquos name = its value The format of the value tells the compiler what its Data Type is

Use the following declarations as needed in your programs Substitute the name you wish (without the quotes) for ldquonamerdquo in the examples

bull For an integer constant

o Public Const Starting_Count = 14

o No decimal point indicates that the value is an integer

o lsquoarsquo (the single quote signs are required) denotes the integer number equivalent of a the ASCII code for lower case letter ldquoardquo

o lsquotrsquo (single quotes required) denotes the integer number equivalent of the ASCII ldquotabrdquo character

bull Text constants are declared using double quotation marks

o MyName = ldquoMikerdquo

o Special characters may be embedded in the text

String2 = ldquoabtcdrdquo would produce the letters ldquoabrdquo followed by a tab and then ldquocdrdquo (ab cd)

bull For a single precision floating point constant add a trailing ldquoFrdquo

o Public Const Limit = 273F

o In exponential notation BigNumber = -1573e7F (15730000)

o Or SmallNumber = 12568e-5F (000012568)

bull For a double precision floating point constant omit the ldquoFrdquo

o Public Const Limit = 273

o BigNumber = -1573e7

o SmallNumber = 12568e-5 (000012568)

Number Bases A number may be entered in different bases such as decimal (base 10) or hexadecimal (base 16) The compiler accepts all of these but you must tell it which you are using

The compiler assumes that you are using decimal numbers unless you tell it otherwise Thus ldquo12rdquo will be taken as a decimal number and not hexadecimal

Hexadecimal numbers may be written in either of two ways

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 30: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-9

0x12 or amph12

Both are equivalent to decimal value 18

You may even use negative hex numbers

-0x3A or -amph3A

Special Variables A number of special variables have been predefined to provide special functions in your programs Do not use them as general-purpose variables as their names are reserved words

The compiler automatically applies a blue color code to the special variables as an aid to the user The special variables are described below

Abstime The value of this variable is equal to GMT clock time (eg 132543)

Elapsed The value of this floating-point variable is the number of seconds that have elapsed since the previous execution cycle of the program It is very useful for those instances when you wish to do something at a periodic rate

This is a much better technique that counting program execution cycles to determine elapsed time For example with the counting technique the time period would change if you changed the service time class of the function Using Elapsed makes the timer immune to such changes and produces a more accurate and repeatable time interval

Say you wish to toggle a digital signal every 5 seconds Assume that the signal is called ldquoOutputrdquo The following program excerpt will change the value of Output every 5 seconds

Public Timer As Double Timer = Timer + Elapsed Calculate the time since the last output IF (Timer gt= 5) Have 5 seconds passed yet Timer = 0 Yes reset the timer Output = NOT Output and toggle the value of Output EndIF

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 31: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-10

Note that we have declared the variable Timer as a double-precision floating-point number This is necessary because the values in the expression can be very small numbers

Also note that we tested for the condition ldquogreater than or equal to 5rdquo That is important because Timer is a floating-point value So the odds of it every exactly being equal to 5 at the time it is checked are very small Using the ldquogreater thanrdquo operator ensures that the comparison will eventually be true

Failover Failover is a Boolean that is normally zero It is true for only the very first program execution cycle that occurs after a DPU failover When used in an expression that tests for it to be true it can be used to do something once after the failover For example

IF Failover Run this code only right after a failover FailoverCntr = FailoverCntr + 1 EndIF

FirstPass FirstPass is a Boolean variable that is normally zero It becomes true (1) only for the very first execution cycle of the program When tested in an IF statement it is useful for doing things only once in a program (eg initializing variables)

IF First Run this code only on the first execution pass for example ErrorCounter = 0 Timer = 0 EndIF

FBAddr The 564-IO bus address of the FB (Fieldbus Buffer) that is linked to this instance of this function block FBAddr only has meaning if the function block is being used for communications with a fieldbus device (eg through a Profibus or HART-capable maxPAC module)

FBCh The channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBCh only has meaning if the function block is being used for communications with a fieldbus device

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 32: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-11

FBDevice The fieldbus device index number that is linked to this instance of this function block FBDevice only has meaning if the function block is being used for communications with a fieldbus device

FBSubCh The sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubCh only has meaning if the function block is being used for communications with a fieldbus device

FBSubSubCh The sub-sub-channel number of the FB (Fieldbus Buffer) to which this instance of this function block is connected FBSubSubCh only has meaning if the function block is being used for communications with a fieldbus device

Gname Gname returns a string that contains the generic name (Gname) of this instance of this function block

HID HID returns a string that contains the hierarchy of this instance of this function block

RelTime Reltime returns the elapsed time since the DPU booted It is used in algorithm calculations

Tagname Tagname returns a string that is the tagname of this instance of this function block

Value Value returns the value passed in a write operation It is valid only in a Write Method (see the section on Methods)

Type Statement Overview

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 33: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-12

The Type statement is used to describe how multiple pieces of data are combined into one string (a data structure) A ldquoWithrdquo statement (described later in this manual) is then used to pick out the individual data fields from the string

One example of the use of the ldquoTyperdquo and ldquoWithrdquo statements would be in communications A serial communications message might consist of multiple fields such as a source address a destination address the message data (which itself might consist of numerous data fields) and a CRC field On the transmit side your program would need to be able to populate these fields into one message string On the receive side your program would need to be able to pick out the individual data fields from the message string ldquoTyperdquo and ldquoWithrdquo give you the ability to easily do those things

Syntax The basic Type definition is declared as follows

Public Type type_name rdquotype_namerdquo is the name of this data structure Field declarations define the pieces of data End Type The data within a structure can be oriented as Big Endian (most significant bitbyte first) or Little Endian (least significant bitbyte first) Choose your orientation by appending ldquoBig Endianrdquo or ldquoLittle Endianrdquo to the first line of the Type definition For example Public Type type_name Big Endian Field declarations End Type If you omit Big Endian or Little Endian from the statement the Atom Compiler will automatically define the bitbyte field mapping to the default orientation used by the processor (Little Endian for the maxDPU4F) There are nine kinds of Data Field declarations Their syntax is similar to one another ltnamegt As Unsigned ltnumbergt This will allocate an unsigned integer field of length number The number may be an explicit integer or a constant Unsigned fields may be 1-31 bits in length If ldquo numberrdquo is omitted the default length is 16 bits

ltnamegt As Integer ltnumbergt This will allocate a signed integer field of length number The number may be an explicit integer or a constant Integer fields may be 2-32 bits in length (for one bit fields use unsigned) If ldquo numberrdquo is omitted the length defaults to 16 bits

ltnamegt As Boolean This will allocate a field assumed to be zero (False) or non-zero (True) Boolean fields may be 1-32 bits in length

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 34: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Variables and Constants and Data Types Oh My

Metso Automation bull 278717 bull 2-13

ltnamegt As Single This will allocate a single precision floating point field the field uses 32 bits and the start is rounded up to the next byte boundary

ltnamegt As Double This will allocate a double precision floating point field the field uses 64 bits and the start is rounded up to the next byte boundary

ltnamegt As String ltnumbergt This will allocate a fixed dimension sub-string field the start is rounded up to the next byte boundary Number is the length of the string in bytes

ltnamegt As Quality ltnumbergt This will allocate an unsigned integer field of length number which will be forced to the values 0-3 The number may be an explicit integer or a constant If ldquo numberrdquo is omitted the field length defaults to 2 bits Quality fields may be 1-32 bits in length For one bit fields the mapping is 0-gt0 = Good and 1-gt3 = Bad

ltnamegt As Fixed ltnumbergtltnumbergt This will allocate a fixed point number field which will be converted to and from a single precision floating point number The first number may be an explicit integer or a constant Fixed fields may be 1-32 bits in length The second number represents the binary point position (shifts of the point to left starting at the right most bit)

Spare ltnumbergt This will reserveskip the number of bits indicated The number may be an explicit integer or a constant

An Example As an example consider a serial communications message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

In a later chapter we will use the ldquoWithrdquo statement to access individual data fields within this message

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data fields contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 35: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 2-14

ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Type Definitions Public Type TempMsg TempMsg is the name of this structure Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type Add additional type definitions here if needed

The names that are given to each piece of the message must be preceded by a period

Just as is done for the IF statement the lines of the ldquoTyperdquo statement are indented to improve readability It is strongly recommended that you follow this format

Once the message bits have been defined we can use the ldquoWithrdquo statement to access the individual data fields that we defined in the structure ldquoTempMsgrdquo This will be illustrated in a later chapter

Caution The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All message bits MUST be listed in the ldquoTyperdquo definition even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 36: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 3

Say it with Expression

Overview Expressions are the meat of the program They along with functions (to be discussed later) are the instructions that the program executes to perform the desired operation

Expressions are essentially equations that may contain public andor private variables public andor private constants shell variables operators (eg + -) and functions In the equation a variable name (located to the left of the ldquo=rdquo) is given the value defined by the expression on the right side of the ldquo=rdquo

Consider the first example below The value of Input 1 is added to the value of Input 2 The variable called ldquoResultrdquo is then set to that calculated value

Some simple examples of expressions are

bull Result = Input1 + Input2

bull AverageTemp = ((Temp1 + Temp2 + Temp3 + Temp4) 4)

bull EveryOtherBit = InputByte amp 0x55

As the last expression shows expressions do not have to be arithmetic equations The example shows how logical bit-by-bit ldquoANDingrdquo can be used to select only certain bits from a data word

In the examples you can see that certain characters (the operators) are shown in red The compiler does this automatically to let you know that it considers those red items to be operators This can help you avoid program errors caused by mistyping or illegally naming variables For example If you had named a variable ldquoTemp2rdquo the red ldquordquo should alert you to the fact that the compiler is assuming that you wish to divide ldquoTemprdquo by ldquo2rdquo It is not treating ldquoTemp2rdquo as the name of a variable

Operators Operators are used to tell the compiler how to combine values For example the ldquo+rdquo operator tells the compiler to add the value on its left to the value on its right

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 37: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-2

Some operators are designed to work only with specific data types For example the ldquoamprdquo symbol is used to perform a logical bit-by-bit AND of two digital data values Thus it would not make sense to AND two floating-point numbers or a text string with a Boolean variable

The following sections describe the operators

Arithmetic Operators Use these on integer and floating point values

+ addition (A + B)

- subtraction (A ndashB)

multiplication (A B)

division (AB)

A POW B This operator raises A to the power of B (eg 3 POW 2 is 3 squared = 9) An alternate form is POW(A B)

MOD or (A MOD B A B) modulo division of X by Y See the chapter on Functions for more information

Logical Operators Logical operators operate only on digital values Their function is based upon the rules of Boolean algebra

NOT or Logical inversion of a value (eg if A = True NOT A is False) The output is a Boolean Integer or Boolean input values are permitted

AND Logical AND of two values The output is a Boolean The result is 1 only if both input values are non-zero Integer or Boolean input values are permitted

OR Logical OR of two values The output is a Boolean The result is 1 only if at least one of the input values is non-zero Integer or Boolean input values are permitted

XOR Logical Exclusive-OR of two values The output is a Boolean The result is 1 only if the two input values are different (one is zero the other non-zero) Integer or Boolean input values are permitted

amp Bit-by-bit logical AND (eg 0x07 amp 0x12 is 0x02)

~ Bit-by-bit inversion (eg ~ 0x07 is 0xF8)

| Bit-by-bit logical OR (eg 0x07 | 0x12 is 0x17)

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 38: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Say it with Expression

Metso Automation bull 278717 bull 3-3

^ Bit-by-bit logical Exclusive-OR (eg 0x07 ^ 0xF3 is 0xF4)

Comparison Operators Use these on any values that have the same data type (eg float with float Boolean with Boolean but not float with Boolean)

The comparison operators are used to test (compare) two values (eg Is value A greater than value B) Since the answer to such a question can only be Yes or No the output of the comparison is always a Boolean value The value is a ldquo1rdquo if the comparison test passes The output value is ldquo0rdquo if the comparison test fails These comparison operators are frequently used in ldquoIFrdquo statements to make decisions based on the relative values of the parameters

= or == (2 equal signs) or EQ Is A equal to B (eg A = B A ==B A EQ B)

NE or = or ltgt Is A not equal to B (eg A NE B A = B A ltgt B)

GT or gt Is A greater than B (eg A GT B A gt B)

LT or lt Is A less than B (eg A LT B A lt B)

GE or gt= Is A greater than or equal to B (eg A GE B A gt= B)

LE or lt= Is A less than or equal to B (eg A LE B A lt= B)

String Operators + This is used to concatenate text strings (eg ldquoCatrdquo + ldquoDogrdquo is ldquoCatDogrdquo)

Order Operators Parentheses are used to determine the order in which the operations in an equation are performed Without parentheses equations are calculated from left to right with multiplications and divisions being done on the first left to right pass and then additions and subtractions done on the second left to right pass Depending upon the equation this can produce unexpected results

For example consider the equation

Y = 4 + 3 2

According to the rules listed above the calculation would produce an answer of Y = 10 (3 times 2 = 6 plus 4 = 10) However what if the equation writer wanted the answer to be 14 (the sum of 4 and 3 multiplied by 2)

Parentheses operators are used to force the order of calculations within an equation Operations inside parentheses are calculated first If there are

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 39: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 3-4

multiple sets of parentheses they are executed right to left If parentheses are nested (one set within another) the inner most set is calculated first

Our previous example can be rewritten using parentheses to force the compiler to calculate the equation in the manner the programmer desired

Y = (4 + 3) 2

The parentheses tell the compiler to add 4 and 3 before performing the multiplication

Even in cases in which the order of calculations is not ambiguous or does not need to be forced it is often a good idea to use parentheses to improve the readability of an equation

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 40: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 4

Built-in Functions

Built-in functions are essentially prewritten programs that you may use within your program to perform operations that would otherwise require you to do a lot of additional programming if you had to write them yourself The compiler supports many built-in functions They may be used within expressions

An Abundance of Functions

The compilerrsquos built-in functions are listed below Some functions only work on specific data types Consider y = cos(x) the trigonometric cosine of the angle X The expression only makes sense if X is a numeric value You cannot take the cosine of a Boolean value or of a text string

Like operators functions are automatically colored red by the compiler

In the following examples the symbols A B X Y etc represent input values for the functions Any or all of them may be replaced with an expression For example Sin(2y3) is a valid expression

Trigonometric Functions Trigonometric functions may only be applied to numeric values (integer or floating point)

The measurement unit of the value applied to the function (eg X in the sin(X)) is radians There are 2П (628318) radians in 360 degrees

Sin(X) The sine of the angle X

Cos(X) The cosine of the angle X

Tan(X) The tangent of the angle X

ASin(X) The arcsine of the angle X

Acos(X) The arccosine of the angle X

Atan(X) The arctangent of the angle X

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 41: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-2

Mathematical Functions Mathematical functions may only be applied to numeric values Unless otherwise noted they may accept and produce either integer or floating-point values

Abs(X) The absolute value of X (eg Abs(-5) is 5)

Log(X) The base 10 logarithm of X (eg Log(100) is 2) ldquoXrdquo must be greater than zero If you try to take the log of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the log of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Ln(X) The natural (base e) logarithm of X (eg Ln(100) is 46) ldquoXrdquo must be greater than zero If you try to take the Ln of a negative number you will get an answer of the form ldquo-1INDrdquo (indeterminate) If you try to take the LN of 0 you will get an answer of the form ldquo-1INFrdquo (infinite)

Exp(X) ex (2718 to the power of X) This is valid for negative 0 and positive numbers

Max(A B C hellip) The output value is equal to the largest of inputs A B C D or hellip (eg Max(4852) is 8)

Min(A B C hellip) The output is equal to the smallest of inputs A B C D or hellip (eg Min(4852) is 2)

Median(A B C hellip) or Limit(A BC hellip) The middle value of the inputs (eg Median(345) is 4 or Limit(345) is 4)

Mean(A B C hellip) The average of the input values (eg Mean(10 30 40 50) is 325) If the input values are integers the result will also be an integer

Pow(X Y) X raised to the power of Y An alternate form is X POW Y (eg POW(32) is 9 3 POW 2 is 9)

Mod(X Y) Modulo divide of X by Y This can also be written as X Mod Y or X Y Both X and Y must be integers Mod returns the remainder from the division (eg 7 Mod 2 is 1 (2 goes into 7 three times with a remainder of 1)

String Functions String functions work on text Except for the ldquoFindrdquo function their output is also a text string

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 42: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Built-in Functions

Metso Automation bull 278717 bull 4-3

Left(XY) Get (return) the left-most Y characters from text string X (eg Left(ldquogoatrdquo 2) is ldquogordquo

Right(XY) Get the right-most Y characters from text string X (Eg Right(ldquogoatrdquo 2) is ldquoatrdquo)

Mid(XYZ) Skip the first Y characters of text string X and then get the next Z characters (eg Mid(ldquoanimalrdquo 3 2) is ldquomardquo)

Find(XY) Search string X for string Y and return the location (index) of the start of the matched string (eg Find(ldquoanimalrdquo ldquonimrdquo) is 2) If string Y is not found the function returns 0

Length(X) This function measures and returns the length (number of characters) of the input string not including the null character that terminates the string (eg Length(ldquoanimalrdquo) is 6)

Trim(X) This function removes trailing blank characters from the input string (eg Trim(ldquoDog rdquo) returns ldquoDogrdquo)

Pad(XY) This function makes a string longer by adding blank characters as necessary to increase string X to Y characters long (eg Pad(ldquoDogrdquo 5) returns ldquoDog rdquo (Dog is followed by 2 spaces)

Pad(X Y Z) This is the same as Pad(XY) but instead of using blanks character Z is used to lengthen the input string (eg Pad(ldquoDogrdquo 5 ldquoardquo) produces ldquoDogaardquo)

Quality Functions Quality(X) This function returns the quality number of input X The output values are 0 for good quality 1 for doubtful 2 for substitute and 3 for bad quality This function can be used to prevent making decisions on unreliable input signals

bull Eg Assume Temperature1 has bad quality then QualTemp1 in the following expression will have the value 3

o QualTemp1 = Quality(Temperature1)

Best(ABC hellip) This function returns the quality number of the best of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg Assume that T1 has bad quality T2 has good quality T3 has substitute quality and T4 has doubtful quality In the following equation SigQual will have the value 0

o SigQual = Best (T1 T2 T3 T4)

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 43: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-4

Worst(ABC hellip) This function returns the quality number of the worst of the input signals applied to it The output value can be 0 1 2 or 3

bull Eg With the same input signals as in the previous example SiqQual will be equal to 3

o SigQual = Worst (T1 T2 T3 T4)

Force(X Y) This function makes the quality value of input X to be Y and it returns value Y

bull Eg Assume that the quality of signal Temperature1 is doubtful (ie its quality value is 1) In other words SigQual = Quality(Temperature1) has the value of 1

bull But if we use the function SigQual = Force(Temperature1 3) the quality of Temperature1 will now be equal to 3 and SigQual will now be equal to 3

Communications Functions Two functions are provided specifically for use when creating custom compiled atoms for communications purposes

Communications atoms require the use of an output buffer to hold the outgoing message until it has been transmitted and an input buffer to temporarily hold the message that was just received until your program has a chance to read it

Available(X) is used to test when the output buffer X is empty and ready to accept a new transmit message Available will be set to a 0 when the buffer is full (the message has not yet been sent) It will be set to a 1 when the buffer is empty and ready to accept a new message Your program must not place a new outgoing message into the output buffer until it sees that Available(X) is true Otherwise your first message will be overwritten by the second

In a program Available is typically placed in an IF statement to see when a new message may be sent

bull Eg IF Available(Out) Now place the new message in the

buffer EndIF

In the example shown above ldquoXrdquo has be replaced with the name that was declared for the output buffer (see the chapter on Declarations) It is possible to use more than one output buffer in a program Give each one a unique name (eg Out1 and Out2)

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 44: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Built-in Functions

Metso Automation bull 278717 bull 4-5

Available(Y) is used to test when the input buffer Y contains a newly received message Available will be set to a 1 when a message has been received and placed in the input buffer That should be your programrsquos signal to read the message from the buffer Reading the Available(Y) flag resets it However the flag will retain its true value for the rest of the program execution pass It will be automatically reset before the next execution pass begins

In a program Available is typically placed in an IF statement to see when a new message has arrived

bull Eg IF Available(In) Now read the message from the buffer

EndIF

In the example shown above ldquoYrdquo has been replaced with the name that was declared for the input buffer (see the chapter on Declarations) It is possible to use more than one input buffer in a program Give each one a unique name (eg In1 and In2)

CRC16(XY) is used to calculate the 16-bit CRC of a string (eg the contents of a communications input or output buffer) CRC (Cyclic Redundancy Check) is a string that is typically used to error-check a data string For example in a communications system a CRC is calculated for the message to be transmitted and it is sent along with the data message At the receive end the CRC of the received message is calculated and compared to the CRC string that was attached to the data message If they do not match a receive error has occurred

In CRC16(XY) X is the input string (ie the name of the communications buffer that holds the string) and Y is the ldquoseed polynomialrdquo that is used in the calculation Currently Y must be ldquoFFFFrdquo (without the quotes) CRC16(XY) returns the calculated 16-bit CRC code

bull Eg RcvdCRC = CRC16(In1 FFFF) Calculate the CRC of the string located in buffer In1

Schedule(X Y Z) tells the compiler to send out (transmit) the message contained in the output buffer named ldquoXrdquo It will return the value of True (1) if the output buffer contains a message and is ready to be sent

Y and Z are optional parameters

Y is the time (in seconds) after the Schedule instruction is executed before the priority for sending the buffer is set to critical Once it goes to critical priority it is more likely that the buffer will be sent out very soon If the DPU is not busy the buffer might be sent out even before its priority goes to critical

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 45: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-6

You might want to use a ldquoYrdquo value of 5 or 10 seconds for a value that does not change very often such as temperature On the other hand you would probably want to use a value of 0 for a custom block that is doing something that is time-sensitive like Modbus communications If Y is not specified (Eg Schedule(out)) it is assumed to be zero

Parameter Z is used only when your system has redundant serial modules In such a case each serial module has its own FB block Parameter Z is used to specify the 564-bus address of the specific FB (and therefore the serial module) to which you want to send the output buffer

Examples

bull Schedule(out_buf1) Send the buffer as soon as possible

bull Schedule(out_buf1 0) This is the same as above

bull Schedule(out_buf1 5) Wait for 5 seconds before bumping the priority to critical

bull Schedule(out_buf1 0 50) Use the serial module whose address is 50 decimal

Unschedule(X) tells the compiler to cancel the scheduling (sending) of output buffer X and to mark the buffer as being available It is used to recover from an error condition when you want to clean up and start over Unschedule will have no effect (and no error code will be returned) if the unschedule is executed after the output buffer has already been sent

Shell Functions Shell functions operate on shell variables

Command(XY) tests shell variable X to see if it has been written If it has global variable Y is updated and Command returns the value 1

Command is used to trigger portions of your program to run only when the input shell variable has been updated by the external source In other words the program loop idles until it gets a newly written input At that time it processes the new input according to the instructions in your program Without the use of the Command variable that code would run continuously In some situations that is not desirable

The Command function does not use the actual value of the variable to determine that the input has been updated Rather it uses the time stamp that the system attaches to the value when it is written The Command function compares the time stamp of the last update of the global variable with the time stamp of the last update of the shell variable When they do not match the system declares that the shell variable has changed

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 46: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Built-in Functions

Metso Automation bull 278717 bull 4-7

For example consider a shell variable that is used to reset some counters within your program Obviously we would not want to reset the counters during each program pass or the counters would always equal 0 The Command function can help

bull Assume that the name of the shell variable being monitored is RstCntrs and that lRstCntrs is a global variable that we use in the program to store the previous value of the shell variable

IF Command(RstCntrs lRstCntrs) Was shell variable RstCntrs written

NumRcvdMessages = 0 Yes reset the counters NumSentMessages = 0 NumErrors = 0

EndIF Since the Command function uses the time stamp of the value instead of the actual value it does not matter what value is written to the shell variable The new value can even be the same as the previous value and it will still trigger the code to run

Complex(XY) Complex variables are wired to a single input on the shell but contain many associated values (out range hi range low etc) Complex(XY) provides a mechanism for picking out the particular value in which you are interested

ldquoXrdquo is the name of the complex shell variable and ldquoYrdquo is the index number of the desired value Index 0 is always an integer that represents the type of the complex input (eg for standard forceback or incremental control) Index 1 is called the Primary value (usually Out) and is the one that you would get if you wired the complex variable to a float variable The values returned by the remaining index numbers depend upon the structure of the complex variable For more information on complex variables please refer to the Function Blocks Userrsquos Guide 278589

If the Complex variable is wired to a shell variable that has been defined as a float Complex(X 0) will return 0 as the type Complex(X 1) will return the value of the float and all other index values (Y) will return 0

IsWired(X) returns a 1 if shell variable ldquoXrdquo is wired (ie if it has a signal listed in its reference field)

A typical use would be in an IF statement to set the value of the Shell Variable to some default value if it is not driven by a signal

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 47: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 4-8

bull Eg IF (IsWired(Reset) = 0) Is shell variable ldquoResetrdquo wired

Reset = 0 No so set the reset input to 0 since it is not being driven

EndIF

Prival(X) returns the primary value of shell variable X It is the equivalent of Complex(X 1) See the description of Complex(XY) for more information

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 48: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 5

Subroutines amp User-Defined Functions

Overview Subroutines and user-defined functions are named sections of a program that perform a specific task They are primarily used to perform functions that will be used over and over again So rather than duplicating the code to do a repeated operation many times the user defines the operation as a subroutine or function and ldquocallsrdquo it by name whenever that operation is needed The calling program may pass values(s) to a subroutine or function if desired

The only real difference between a subroutine and a function is that functions return a value to the main program Subroutines cannot return any values However you could get a value out of a subroutine or function by giving (assigning) the value to a public variable while in the subroutine or function

Assume that you are writing a custom compiled function block whose purpose is to provide communications with a foreign device and to translate the bits of the messages into maxDNA attributes Among other things such a program would need to perform operations like sending each message receiving each response and checking each response for CRC errors

It would probably make sense to create subroutines or functions for each of the often-repeated operations For example one subroutine could be used to transmit a message another could be used to check the CRC of a received message and so on Structuring the program in such a manner could greatly reduce the amount of typing that you had to do Moreover it would make it easy to reuse those functions in other programs Why reinvent a receive subroutine if you have already written and debugged one

Another good use for a subroutine or user-defined function is to make a program easier to read If you have a complex in-line program it would be easier to read and maintain the program if functions were moved from the in-line code to subroutines andor user-defined functions It also helps a lot if you give your functions and subroutines names that clearly describe their use (Eg Send_Output_Buffer)

When you use subroutinesfunctions your program is organized into two sections The ldquoMainrdquo section contains the major portion of the programrsquos

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 49: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-2

logic and the lines that call the subroutinesfunctions It must be located at the end of the program listing The subroutine(s)function(s) must be located somewhere before the Main program starts That is because the compiler goes through the program from top to bottom and it needs to see the definition of every variable constant function and subroutine before it is used

Subroutine and function definitions are color-coded blue by the compiler

Neither subroutines nor functions may call themselves or call something further down (forward) in the program In fact no forward references are allowed at all regardless of who makes them These rules provide important protection against locking the program up in an endless loop

Syntax for Subroutines A subroutine has two parts One is the program line that calls it and the other is the function itself

The line in the main program that calls the subroutine is written as follows

ldquostringrdquo() where ldquostringrdquo is the name that you have given to your subroutine

Eg Send_Message()

The first line of the subroutine itself is defined as follows

Private ldquoStringrdquo() rdquoPrivaterdquo may be omitted it is implied

Eg Private Send_Message()

or Send_Message()

The last two lines of the subroutine must be a ldquoReturnrdquo and then an ldquoEnd Subrdquo statement ldquoReturnrdquo directs the program execution back to the main program ldquoEnd Subrdquo tells the compiler where the subroutine code ends

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 50: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Subroutines amp User-Defined Functions

Metso Automation bull 278717 bull 5-3

An example of a call to a subroutine and the subroutine itself are shown below The ldquoWithrdquo statement is not a required component of a subroutine It will be explained later

Private Sub Send_Message() With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = 33 DataByte2 = 57 End With Schedule(out 0) Send the output buffer Return End Sub Main Program Send_Message()

Note that the subroutine is located before the main program As mentioned earlier this is a requirement Everything must be defined before it is used

Furthermore the sample subroutine was not given (passed) any values by the calling program However a value or values could have been passed to the subroutine with a slight modification to the syntax as follows

Private Sub Send_Message(Data1 As Integer Data2 As Integer)

With out As MsgFormat Build the message id = 1 CmdType = Send DataByte1 = Data1 DataByte2 = Data2 End With Schedule(out 0) Send the output buffer Return

End Sub

Main Program Send_Message(33 57) the values 33 and 57 are being

passed to the subroutine named ldquoSend_Messagerdquo

As the previous example shows in order to pass a value(s) to a subroutine the data type must be declared within the subroutinersquos definition If more than one value is being passed they must be separated by commas The data values contained in the line that calls the subroutine must be listed in the exactly same order as they are defined within the subroutine That is how the compiler knows that Data1 = 33 and not 57

Syntax for User-defined Functions The syntax for a user-defined function is almost identical to that of a subroutine Besides the changing the word ldquoSubrdquo to ldquoFunctionrdquo the User-

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 51: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 5-4

defined function also requires a data type declaration for the value it returns See the following example

Private Function MyAverage(Input1 As Float Input2 As Float) As Float The last ldquoAs Floatrdquo is the data type for the value that will be returned

Private Avg As Float The data type for ldquoAvgrdquo must be declared before it is used Avg = (Input1 + Input2)2 Return Avg This line tells the compiler to return the variable named ldquoAvgrdquo

End Function Main Program Answer = MyAverage(373 881) pass the values 373 and 881 to the MyAverage function and assign the returned result to the variable named ldquoAnswerrdquo The word ldquoPrivaterdquo in the function definition is optional It would work the exactly the same if it were defined as Function MyAverage(Input1 As Float Input2 As Float) As Float The internal variables of functions and subroutines are typically declared as private to prevent conflicts with other variables having the same name This permits easy reuse of subroutines and functions in other programs Declaring them as private also means that they wonrsquot be transferred over the DPU backup link Transferring them would serve no purpose and needlessly consume DPU resources

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 52: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 6

Executable Statements

Overview Executable statements provide additional functionality and logical control to a program The compiler color-codes executable statements blue

Let Let provides an assignment function (ie assigning a value to a variable) Let may be used in several different forms In some cases the word ldquoLetrdquo is implied and does not actually appear on the program statement The forms of Let are shown below

Let MyVariable = A + 3 Sets ldquoMyVariablerdquo to the value of the expression ldquoA + 3rdquo

MyVariable = A + 3 Same as above with an implied ldquoLetrdquo

In the previous two forms of Let the data type of the result is ldquocastrdquo (converted to) the data type declared for ldquoMyVariablerdquo If A is an integer ldquoA + 3rdquo is an integer However the result will be converted to a float if that is how MyVariable was declared

The following three forms of ldquoLetrdquo are used to override the quality of a variable and force it to a certain value

Let Quality MyVariable = A + 1 Sets the quality of MyVariable to the value of A + 1

Quality MyVariable = A + 1 Same as above with an implied ldquoLetrdquo

Quality(MyVariable) = A + 1 Same as above

IF The IF statement gives the program the ability to test an expression and to execute or not execute other statements depending on the result of the test In other words it makes decisions to control program flow

As with the Let statement there are multiple forms of the IF statement

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 53: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-2

IF ldquoexpressionrdquo rdquoexpressionrdquo must have a TrueFalse result (such as is produced by a comparison operation) Execute these lines only IF ldquoexpressionrdquo is TRUE EndIF IF ldquoexpressionrdquo is FALSE skip the previous lines Eg IF Cntr gt 100 check value of Cntr Cntr = 0 reset cntr if the count is more than 100 EndIF The previous example could also have been written as IF Cntr gt 100 Then Added ldquoThenrdquo for clarity Cntr = 0 EndIF Or IF Cntr gt 100 Then Let Cntr = 0 A single line form No EndIF is needed for this format IF statements may also be written that evaluate multiple cases instead of just one For example IF Pressure lt 10 MessageText = ldquoPressure is too lowrdquo Setpoint = Setpoint + 5 ElseIF ((Pressure gt= 10) AND (Pressure lt 50) MessageText = ldquoPressure is OKrdquo Else MessageText = ldquoPressure is too highrdquo Setpoint = Setpoint - 10 EndIF In the previous example IF statements are used to test for two conditions (Pressure lt 10 and for Pressure between 10 and 50) The case in which Pressure gt= 50 does not need an explicit comparison test because it is the only possible case remaining Thus there is no ElseIF statement for it The ldquoElserdquo says to execute the succeeding lines because the Else would not have been executed if the previous tests had not failed Only the first test that produces a true result has its associated program statements executed The other test cases are automatically skipped over and program execution resumes after the EndIF statement In these examples the statements that are executed when the IF statement is true are indented past the beginning of the IF statement This format is followed to improve the readability of the program It is strongly recommended that you follow this format in your programs

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 54: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Executable Statements

Metso Automation bull 278717 bull 6-3

With The ldquoWithrdquo statement is used to map strings to structures That is it provides a description of how to decode or encode the individual pieces of information in a string variable

It is used in conjunction with the ldquoTyperdquo statement First the ldquoTyperdquo statement is used to define the data structure Then the ldquoWithrdquo statement is used to pick out the individual data fields within the structure

ldquoWithrdquo is extremely useful in function blocks that deal with communications protocols A message is typically a serial string that is built up from individual pieces (bits bytes etc) each having its own meaning In order to write a program (custom compiled function block) to transmit and receive such a message it would be extremely useful to be able to pick out and manipulate individual bits from the string The ldquoWithrdquo statement provides this function

The format of the With statement is

With name_of_string As name_of_structure_definition type definitions go here End With

For example consider a message that is 40-bits long and is defined as follows Assume that the bits are numbered 1 ndash 40 with number 1 being the most significant bit This is the example message structure described in the section on the ldquoTyperdquo definition It is repeated here for your convenience

Bits 1 ndash 2 Destination address (Letrsquos call these bits Daddr1-2)

Bit4 4 Source address (Letrsquos call this bit Saddr1)

Bits 5 - 8 Status flags (Letrsquos call these bits Status1-4)

Bits 9 ndash 40 Temperature (Letrsquos call these bits Temp (a 32-bit value))

We can use the ldquoWithrdquo statement to decode the message string as follows Assume that the message has been received and is located in the communications input buffer that we have named ldquoIn1rdquo Further assume that we have named the structure used to define the components of this type of message ldquoTempMsgrdquo

Before we can use the ldquoWithrdquo statement we need to define the message structure and the data types contained therein This is done with a ldquoTyperdquo statement as follows The ldquoTyperdquo statement must be located before the ldquoWithrdquo statement and is usually placed in its own section denoted by comments

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 55: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 6-4

Type Definitions Public Type TempMsg Daddr As Unsigned 2 Daddr is 2 bits long Saddr As Unsigned 1 Saddr is 1 bit long

Status1 As Unsigned 1 First status bit

Status2 As unsigned 1 Second status bit

Status3 As Unsigned 1 Third status bit

Status4 As Unsigned 1 Fourth status bit

Temp As Single Temperature End Type

The names that are given to each piece of the message must be preceded by a period

The order in which the lines in the type definition appear is critical They MUST match the actual order of bits in the message Do NOT omit any bits All bits in the message must be listed even if you do not need to use them For instance assume that we do not care to decode the source address If we left it out of the definition the compiler would think that the Status and Temperature fields began one bit sooner than they really do That would result in a mistake when we tried to decode those fields

Once the message bits have been defined we can use the With statement to access the individual message pieces that we defined in TempMsg

With In1 As TempMsg Decode the string in buffer In1 using definition TempMsg Destination = Daddr Source = Saddr

StatBit1 = Status1 StatBit2 = Status2 Temperature = Temp

StatBit3 = Status3 StatBit4 = Status4 End With

As you can see from the example above unlike the Type definition the order of the fields in the With statement does not matter Also note that we must use the period that precedes each name

Now we have variables (StatBit1 Temp etc) whose values have been decoded from the received message They can be used as you would use any other variable

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 56: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Executable Statements

Metso Automation bull 278717 bull 6-5

If we were not interested in the value of Source StatBit3 or any other data field we could have eliminated those lines from the With statement However they must still appear in the Type definition

Just as is done for the IF statement the lines of the With and Type statements are indented to improve readability It is strongly recommended that you follow this format

Just as a ldquoWithrdquo statement can be used to retrieve individual data fields from a data structure it can also be used to place values into the individual data fields Assume that we wish to create an outgoing message with the same format and bit definitions as before Since the bit definitions of the outgoing message are the same as the received message we can use the existing Type definition It does not need to be entered into the program twice However just as when decoding a message the Type definition must appear before it is used in the program

To place data values into the data fields defined by the Type statements we use the ldquoWithrdquo statement However the expressions within it are rearranged slightly because we are putting data values into the fields instead of taking them out Thus

With Out1 As TempMsg Out1 is the output bufferrsquos name Daddr = StnAddr Status2 = Flag2 Status3 = Flag3 Status4 = Flag4 Saddr = MyAddr

Status1 = Flag1 Temp = MyTemperature End With

The names to the right of the ldquo=rdquo are the variables that contain the values that we wish to place in the outgoing message Note that the elements of TempMsg all have periods preceding them That is a requirement As in the decoding example the order of the lines in the ldquoWithrdquo statement do not matter Further if we do not care about the value of a field(s) that line(s) may be omitted from the ldquoWithrdquo statement However the structure (Type) definition must be complete and all of its lines must be in the correct bit order

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 57: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 7

Therersquos a Method to the Madness

Overview A method is a piece of executable code that only executes when the named shell variable is being accessed

A method provides the user with a way for an external access to the function block to trigger on-demand execution of some part of the program This may be done to save storage space or to improve performance by not wasting CPU cycles to execute code whose result is seldom needed

The compiler supports three types of method functions (a fourth the Event method is listed in the Syntax help but it has not been implemented) The read method only executes when the named shell variable is being read (immediate read or subscription) The write method only executes when the named shell variable is written The check method executes when the shell variable is written Its purpose is to see if a write to the variable is permitted For all of these methods the access that triggers the execution comes from outside of the function block not from within

For example assume that every once in a while the user needs to read a value from the compiled function block Further assume that the calculation to produce that value is rather involved The program could have been written to calculate the value during every program execution cycle and to store it away in case it was every asked for But instead it was decided to calculate the value only when it was asked for The mechanism to do this is to use a read method When the user accesses the read method through the shell variable it triggers the calculation to run and to provide the requested value

Another reason to use a read method for this could be that the output value is a very large string Rather than continually waste a lot of storage space to hold the output string the programmer uses a method to produce the string on demand

If a read method exists for a shell variable then a write method must also exist or the variable will become read-only If your application does not require the write method to do anything just add a dummy write method that simply does a return This is explained further in a following section

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 58: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-2

The executable portion of a method may contain expressions function calls subroutine calls IF statements etc

Variables that are declared within a method (to be used only within the method) should be private If you wish to pass a variable outside of the method it is permissible to pass it through a global variable

Read Method The syntax for a read method is as follows

Read Method name of shell variable Place the executable code here

Return internal variable name End Method

For example here is a read method that is used to do a very simple on-demand calculation In the example the shell variable is named ldquoShaftSpeedrdquo The Read Method converts the shaftrsquos rotational speed in revolutions per second to revolutions per minute before passing the value out to the shell

Read Method ShaftSpeed RPS to RPM units conversion RevsPerMin = RevsPerSec 60 Return RevsPerMin ldquoReturnrdquo causes an exit from the method and the result to be passed back through the shell variable ldquoShaftSpeedrdquo End Method

The Read Method portion of the function block program does not execute until someone outside of the function block reads the variable ldquoShaftSpeedrdquo

Write Method The syntax for a write method is as follows

Write Method name of shell variable Place the executable code here

Return End Method The following is an example of a write method This program uses a write method to force a conversion of the entered value from degrees Centigrade to degrees Fahrenheit A read method is used to display the entered value Without the read method the entered value would always show ldquo0rdquo in the browser even though the program works and the correct result is displayed in OutTemp Compile the program with and without the read method and see for yourself

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 59: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Therersquos a Method to the Madness

Metso Automation bull 278717 bull 7-3

Public DisplayC As Single Declared as a Public variable so that its value may be used in both methods Write Method TemperatureC Conversion of degrees C to F Private TempF As Single

DisplayC = Value put entered value in DisplayC TempF = Value 18 + 32 OutTemp = TempF Display the result OutTemp is an output shell var

Return End Method Read Method TemperatureC Input shell variable (Deg C) Return DisplayC Display the entered temperature in the shell variable TemperatureC End Method

When a value is written to the shell variable ldquoTemperaturerdquo the Write Method code executes and converts the value from Centigrade to Fahrenheit The result is placed into variable DisplayC for use elsewhere in the function block When the Return is executed the value of DisplayC is placed into shell variable TemperatureC so that it may be accessed outside of the function block

As mentioned previously you should add a write method whenever you have a read method If your program does not require the write method to do anything make it a dummy method as follows

Write Method name_of_Shell_Variable_used_in_Read_Method Return Dummy Write Method

End Method

For example

Read Method HartLongTag Return Trim(longTag) End Method Write Method HartLongTag Return End Method In the previous example a read method is used to trim (remove trailing blanks) from the text string ldquolongTagrdquo when the shell variable HARTLongTag is read The program did not require a write to HARTLongTag so a dummy write method was created

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 60: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 7-4

Check Method The Check Method is applicable to floating-point integer and text data types The syntax for the check method is as follows Check Method name of shell variable Place the executable code here Return End Method

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 61: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 8

Things to Make Your Programming Life Easier

Overview This chapter is a collection of suggestions that will hopefully make it easier for you to write more easily maintainable programs

Program Template Using a consistent layout for you programs will help make them easier to understand and to maintain To this end it is suggested that you use the following template for your programs

Just add your program statements to the appropriate sections of the template

Program Name Description Rev amp Date C O N S T A N T S T Y P E S V A R I A B L E S S U B S and F U N C T I O N S M E T H O D S M A I N R O U T I N E

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 62: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 8-2

Reusing Custom Compiled Function Blocks You may reuse an existing custom compiled function block in other databases The method for doing this is the same as for any other custom function Refer to the maxDPUTools manual (278597) for details

Preserve Your Program Source A little care must be taken if you wish to modify an existing program source file (atom) when creating a new compiled function block That is because of the embedded link in the program that points to the database used to define its shell variables You can see the link and the name of the atom file by clicking on the Shell Variables button in the compiler

If you are not careful you might accidentally change the original function block when creating your new one

The following is one possible procedure designed to prevent any such problems

Assume that your database is called MyDatabase and that it contains the shell variable definitions for your first function block called Function1 The source program is called Function1atom Further assume that you wish to create a new function called Function2 and it is similar to Function1 Due to the similarity of functions you wish to create Function2 by modifying Function1 rather than starting from scratch

Begin by making a backup copy of the MYDatabase4F and Function1atom ndash just in case

Open the database and click on the Custom tab

Right-click on Function1 Copy and then paste it into the custom folder

Right-click on the copy and rename it Function2

Right-click Function1 and start the Atom Compiler Select all of the lines of the program and copy them Close the compiler

Rightndashclick Function2 and start the Atom Compiler Since no program exists for Function2 a dialog box asks you to select an atom Click open to accept the default name of Function2 for the new file Paste the copied program into the new file Save it

You may now modify the Function2 source program as you wish without danger of changing Function1

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 63: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Metso Automation bull 278717 bull

Chapter 9

Putting it all Together

Overview The information contained in this book is perhaps best illustrated by means of a custom function block that performs a useful function

There is a group in the maxDPUTOOLS Standard Function libraries called Examples Sample functions are included in this group for educational purposes The examples are intended to be used as a starting point for users to create their own similar custom functions Use caution in that the examples may not have all of the functionality that is required for your system Furthermore they have not been rigorously tested Use them in your system at your own risk

Sensor Failure Detector Reading a long program listing even with embedded comments does not provide the best type of training So for this example function we refer the reader to maxDPUTOOLS to see the example function and its associated technical information

The example custom blocks are shipped locked That is standard procedure for custom blocks and is one that we recommend that you follow when creating your own blocks Locking the block serves two purposes It shields the user from the complexity of what is inside the block Thus the user only sees those attributes that are needed to use the block It also prevents a user from accidentally changing and perhaps breaking the function block

We will use the Sensor Failure Detector function as an example This function uses the value of the standard deviation of its input signal to determine if a sensor has failed

Open the database ldquoCmcsconfigsStandardLibraries4F43ExamplesExamples4Frdquo

Click on the Custom tab and then expand the Local Custom BuildingBlocks and Examples groups

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 64: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-2

Click on SnsrFailDetector and press ldquoF1rdquo on the keyboard The SnsrFailDetector help file will open This file contains detailed information on what the function does how to use it and how it works Use this information to understand the function block If you click on the StdDev function and press ldquoF1rdquo you will see its help file The figure shows a portion of the help for SnsrFailDetector

In conjunction with reading the help files you will probably want to examine the internals of the function blocks (eg the source code and comments for the custom compiled StdDev block)

You will need to unlock the function blocks to see what is inside them Right-click on StdDev and select ldquounlockrdquo Click ldquoOKrdquo when asked to confirm the unlock operation See the figure below

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 65: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Pulling It All Together

Metso Automation bull 278717 bull 9-3

Repeat for the SnsrFailDetector function block

Now that the blocks are unlocked you may examine and even modify them For example if you right-click on StdDev the custom compiled function you will now see a menu option for the Atom Compiler (when the block was locked that option was not available) If you select the Atom Compiler option the source code for the StdDev function will open in the compiler window From there it may be examined printed or modified

If you expand the SnsrFailDetector block you will be able to view the functions that it contains Since the block is now unlocked you will be able to view and modify data and reference values If the block were locked you would only be able to view the information

After you have finished examining the internals of the function blocks remember to relock them (Right-click on each function and select ldquoLockrdquo then click ldquoOKrdquo to confirm)

Using the Sensor Failure Detector in Your Own Configuration

If maxDPUTOOLS is not already running start it and select ldquoCreate a new configurationrdquo After choosing a version (43 or later) for the database you will be asked if you wish to import any of the Standard Libraries Click ldquoYesrdquo

Or if you wish to use the Sensor Failure Detector in an existing (version 43 or later) configuration open the configuration and then click on the Custom tab Right-click on the Local Custom folder and select ldquoImport Standard Librariesrdquo

In either case the Import window will open as shown below

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 66: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Atom Compiler Userrsquos Guide

Metso Automation bull 278717bull 9-4

Select the group called ldquoExamplesrdquo (click on the checkbox to the left of ldquoExamplesrdquo) Then click the ldquoImportrdquo button Click ldquoOKrdquo to acknowledge the import

The StdDev and SnsrFailDetector function blocks will appear in the left-hand pane of the Custom window

If you wish to use the SnsrFailDetector in your configuration do it as you would any other function block Go to the ldquoDPU4F-43rdquo tab and add a group to contain the SnsrFailDetector Then right-click on the group folder and select ldquoAdd Blockrdquo The SnsrFailDetector block will appear in the list of available blocks Select it and click ldquoAddrdquo

Assign it a tagname and apply a sensor signal to its input Refer to the SnsrFailDetectorrsquos help file to tune the block

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration
Page 67: Atom Complier User’s Guide - Valmetepsservices.valmet.com/support/archive/DocLibrary/... · 2014-07-15 · Sometimes, though, it is even better to create an entirely new function

Pulling It All Together

Metso Automation bull 278717 bull 9-5

If you wish to modify the SnsrFailDetector or the StdDev function blocks to tailor it to your application you must take care to not modify the original This is especially true of StdDev since it is a compiled block Refer to Chapter 8 and review the section about ldquoPreserving Your Program Sourcerdquo

  • 278717 Rev A1
  • Contents
  • Chapter 1
    • Introduction
      • What is the Atom Compiler
      • Overview of a Custom Function Block
      • Workstation and DPU Versions
      • Using the Compiler A Simple Example
      • Changing the Shell Variables
      • Help
      • Files
      • Compiler Errors
      • Summary
          • Chapter 2
            • Variables and Constants and Data Types Oh my
              • Overview
              • Variables
                • Rules for Naming Variables
                • Public and Private Variables
                  • Constants
                    • Rules for Naming Constants
                    • Public Constants
                    • Predefined Constants
                      • Data Types
                        • Allowable Data Types for Variables
                        • Allowable Data Types for Constants
                          • Declaring Variables and Constants
                            • Declaring Variables
                            • Declaring Constants
                            • Number Bases
                              • Special Variables
                                • Abstime
                                • Elapsed
                                • Failover
                                • FirstPass
                                • FBAddr
                                • FBCh
                                • FBDevice
                                • FBSubCh
                                • FBSubSubCh
                                • Gname
                                • HID
                                • RelTime
                                • Tagname
                                • Value
                                  • Type Statement
                                    • Overview
                                    • Syntax
                                    • An Example
                                    • Caution
                                      • Chapter 3
                                        • Say it with Expression
                                          • Overview
                                          • Operators
                                            • Arithmetic Operators
                                            • Logical Operators
                                            • Comparison Operators
                                            • String Operators
                                            • Order Operators
                                              • Chapter 4
                                                • Built-in Functions
                                                  • An Abundance of Functions
                                                    • Trigonometric Functions
                                                    • Mathematical Functions
                                                    • String Functions
                                                    • Quality Functions
                                                    • Communications Functions
                                                    • Shell Functions
                                                      • Chapter 5
                                                        • Subroutines amp User-Defined Functions
                                                          • Overview
                                                          • Syntax for Subroutines
                                                          • Syntax for User-defined Functions
                                                              • Chapter 6
                                                                • Executable Statements
                                                                  • Overview
                                                                  • Let
                                                                  • IF
                                                                  • With
                                                                      • Chapter 7
                                                                        • Therersquos a Method to the Madness
                                                                          • Overview
                                                                          • Read Method
                                                                          • Write Method
                                                                          • Check Method
                                                                              • Chapter 8
                                                                                • Things to Make Your Programming Life Easier
                                                                                  • Overview
                                                                                  • Program Template
                                                                                  • Reusing Custom Compiled Function Blocks
                                                                                  • Preserve Your Program Source
                                                                                      • Chapter 9
                                                                                        • Putting it all Together
                                                                                          • Overview
                                                                                          • Sensor Failure Detector
                                                                                          • Using the Sensor Failure Detector in Your Own Configuration