PROFINET Master

The PNIO Master emulates a PROFINET RT master in a network. It can be used to 

  • test I/O data exchange with an iRJ45 device via a PROFINET RT connection

  • identify the device via the PROFINET DCP protocol

  • set a station name via the PROFINET DCP protocol

  • set the IP configuration via the PROFINET DCP protocol

  • trigger the Wink command via the PROFINET DCP protocol

  • read/write I&M 1-4 records via the PROFINE RT protocol

  • see alarms generated by the device

The PNIO Master consists of four different tabs which can be selected at the bottom.

The Device Commands tab allows to run basic DCP commands such as the identification of the device, setting the station name aso.

Device Commands

The I/O tab allows to setup and start a PROFINET RT I/O data connection.

I/O tab

The I&M tab allows to read and write the I&M records 1-4 of the device.

Device Commands

The Device Commands tab allows to work with the iRJ45 device using the PROFINET DCP protocol.

To work with an iRJ45 device using PROFINET, scan the network in the Network Navigator, select the required device and then click “Scan device”. The PROFINET Master then sends DCP Ident Req packets to the network and will report how many PROFINET devices in the network replied.

The dialog will automatically close when the device reported back via PROFINET and show the reported data (Station Name, Station Type, IP settings aso) in the Device Commands section.

If no reply from the device is received, an error dialog is shown as depicted in the figure below

The device is now identified as a PROFINET capable device and can now be used with the other functionalities of the PROFINET Master.

As a next step, the symbolic name of the device within the PROFINET network (the station name) can be set by clicking on “Set station name”. A dialog allows to define the new station name.

Per default, the station name is not stored in a non-volatile memory and is reset to an empty string after reboot. To persistently store the station name, check “Permanent” before clicking on “OK”.

After clicking “OK”, the new station is send to the device and the PROFINET Master will report whether the action was successful.

To set the IP configuration (IP address, netmask, gateway) via PROFINET, click on “Set IP settings”. A dialog allows to define the IP settings.

Per default, the IP settings are not stored in a non-volatile memory and are reset to 0.0.0.0 after reboot. To persistently store the IP settings, check “Permanent” before clicking on “OK”.

To visually identify devices in a PROFINET network the PROFINET DCP specification provides the Signal command. An PROFINET device that receives a signal command will show a visual indication which is device dependent and may rang from a blinking LED to a flash LCD display. For example, the iRJ45 Arduino Development board will blink with LED2 upon the reception of such a command.

To trigger the Signal command, click on the “Wink” button. The PROFINET Master will send the appropriate DCP command to the device and report the result.

I/O

The I/O tab allows to establish a PROFINET RT connection with one device to exchange I/O data.

Before working with I/O tab, identify the device via PROFINET by clicking “Scan” in the Device Commands tab.

The PROFINET Master requires information about the configuration of the target device. This information is read from the GSD file that is provided by the device vendor. To read this information, click on “Load GSDML file” and choose the GSD file in the file select dialog.

The I/O configuration consists of the following elements:

  • Language: The language of the module description. English is the default language.

  • Device Access Point: The device access point to connect to.

  • Slots: The list of available slots of the target device

  • Modules: The list of available modules that can be plugged into the slots.

To configure the I/O connection, the required modules need be plugged into the slots. To plug a module, select the module in the Modules list and drag it to the required slot. Not all modules may be plugged into all slots. To remove a module from a slot, right click on the module in the Slot list and select “Remove module”.

The cycle time of the communication is selected via the Device Interval. It specifies the interval between two data frames in ms. The allowed values are specified in the GSD file.

To start the I/O connection, click on “Connect”. After successful establishment, the I/O Data can be seen in the I/O data section of the I/O tab.

 

The figure above shows the I/O data section for a 64 bytes input module in slot 1 and a 64 bytes output module in slot 2. Input/output data values are always shown as hex data.

The I/O data sections is split into the following columns:

  • Module/Submodule: The modules in the order they were plugged to the different slots

  • Data Type: The data type of the data item

  • Input PS/CS: the producer/consumer state of the module if input data is provided

  • Output PS/CS: the producer/consumer state of the module if output data is provided

  • Input Data: the input data of the data item for input modules

  • Output Data: the output data of the data item for output modules

The producer/consumer state shows the PS/CS values as transmitted to/from the device. By hovering of the column with the mouse, a tooltip shows the decoded values.

To edit the PS/CS value, click on the column and select “Edit”. A dialog allows the setting of the new value which is then applied by clicking on “OK”. The consumer state can be edited for input modules, the producer state can be edited for output modules.

Output data can be edited by clicking on the value in the Output Data column. After editing hit the “Enter” key to apply. By hitting the “Esc” key or clicking onto another column, the editing is aborted.

By default, the CS and PS values are set to Good by the PROFINET Master. This value can be configured via File → Preferences → PROFINET RT → IOCS default state / IOPS default state.

Scripting

The PROFINET Master provides a scripting interface to manipulate output data and react on received input data using an integrated Python 2.7 interpreter.

A script can be selected prior starting the connection using the scripting section as shown below.

To select a script, push the “Select script file” button and a file selection dialog will appear which allows to choose the appropriate script file. To clear the currently selected script, push the “Clear Script” button.

The basic structure of a script is shown in the listing below.

######################################################################### # PNIO master script skeleton # ######################################################################### ### # This function is called every time a frame is received # from the device. ### def process_input(): pass ### # This function is called every time a frame is about to be sent. # It contains the complete frame incl. all headers. ### def process_output(): pass ### # This function is called once the PNIO stack reports that # the connection is established. At this point in time, you can # retrieve the position of the individual data items. ### def established(): pass ### # This function is called once when the connection was closed. ### def closed(): pass ### # Called once during init of the script ### if __name__ == "__main__": pass

A script contains of the following elements:

  • a main section called once during the initialization of the script (normally before the connection is established)

  • Function established: called once the PNIO connection is established. In this function, the position of the individual data within the frames can be retrieved as well as basic connection configuration data like watchdog factor etc.

  • Function process_input: called every time a data frame from the slave is received. The frame is passed as raw byte array starting after the header in a global variable in_data

  • Function process_output: called every time before a data frame is sent to the slave. The frame is passed as a raw byte array incl. the header in a global variable out_data

  • Function closed: Called once the connection is closed for cleanup tasks.

The following table describes the different global variables that are available for access in the the scripts.

Name

Description

Type

Available from

Name

Description

Type

Available from

station_name

Name of the station the master is connected to

String

main

mac

MAC address of the station the master is connected to

Byte Array

main

config

Configuration of the PNIO connection. See description below

PnioConnectionConfig instance

established

in_data

Data frame received starting behind the header

Byte Array

process_input

out_data

Data frame to sent to the remote station incl. the header

Byte Array

process_output

out_data_offset

The offset of the output data within the frame

int

process_output

A PnioConnectionConfig object encapsulates the configuration of a PNIO connection. It provides the following functions:

Name

Description

Return Value

Name

Description

Return Value

getModulesToPlug

returns a list of PnioModule instances describing the modules/submodules that shall be plugged into the appropriate slots

a list of PnioModule instances

getWatchdogFactor

returns the watchdog factor

watchdog factor as int

getDataholdFactor

returns the data hold factor

data hold factor as int

getControllerReductionRatio

returns the controller reduction ratio

controller reduction ratio as int

Information of about individual modules is encode in PnioModule and PnioSubmodule instances.

A PnioModule consists of the following functions:

Name

Description

Return value

Name

Description

Return value

getSlot

returns the slot where the module shall be plugged into

slot as int

getName

the name of the module

name as string

getInfoText

InfoText of the module

InfoText as string

getAllSubmodules

returns a list of submodules

list of PnioSubmodule instances

A PnioSubmodule provides of the following functions:

Name

Description

Return value

Name

Description

Return value

getName

returns the name of the submodule

name as string

getDirection

data direction of the submodule

DIR_IN - input

DIR_OUT - output

DIR_INOUT - input/output

getInputSize

the size of input data in bytes

input data size as int

getOutputSize

the size of output data in bytes

output data size as int

getIoInputDataObject

getIoOutputDataObject

returns an IoDataObject describing the input or the output data of the submodule.

IoDataObject instance

getSubslot

the subslot where the submodule shall be plugged into

subslot as int

getDeviceToControllerIoCsObject

getControllerToDeviceIoCsObject

returns the cs IoDataObject object used for input data (controller to device) or output data (device to controller)

 

The following script demonstrates how to access configuration data by printing information about all modules and submodules to the console.

### # This function is called once the PNIO stack reports that # the connection is established. At this point in time, you can # retrieve the position of the individual data items. ### def established(): print("Connected to " + station_name) print("===== Connection params =====") # show basic connection params print("reduction ratio: " + str(config.getControllerReductionRatio())) print("wd factor: " + str(config.getWatchdogFactor())) print("data hold factor: " + str(config.getDataholdFactor())) # show module/submodule configuration print("===== Modules =====") # ignore module 0 as this is the dap module for i in range(1, len(config.getModulesToPlug())): module = config.getModulesToPlug().get(i) print("----- Module " + module.getName() + "-----") print("Description: " + module.getInfoText()) print("Number of submodules: " + str(len(module.getAllSubmodules()))) subs = module.getAllSubmodules() # show all submodules for j in range(len(subs)): sub = subs.get(j) direct = str(sub.getDirection()) print("\t----- Submodule " + sub.getName() + "-----") print("\tData direction: " + direct) if ("DIR_IN" == direct): print("\tInput size: " + str(sub.getInputSize())) if ("DIR_OUT" == direct): print("\tOutput size: " + str(sub.getOutputSize())) if ("DIR_INOUT" == direct): print("\tInput size: " + str(sub.getInputSize())) print("\tOutput size: " + str(sub.getOutputSize())) print("")

Positional data within the frame is encoded in IoDataObject instances:

Name

Description

Return value

Name

Description

Return value

getFrameOffset

the offset of the data within a input frame (DIR_IN or DIR_INOUT) or an output frame (DIR_OUT or DIR_INOUT)

position as int

The following list provides a more complex example for accessing input and output data. It is based on the example project 09_pnio_io_mirror_new_api for the AC/CC. It sets a value to the 8bit output module and measures the time until the value is mirrored back on the first input module.

######################################################################### # This script demonstrates how to use the scripting engine of the # # PNIO master. # # It sets a value to the first output module and measures the time # # unitl that value is received on the first input module. # ######################################################################### from datetime import datetime # global vars in_pos = 0 out_pos = 0 lastval = 0xFF trigger = False expected_val = 0 ### # This function is called every time a frame is received # from the device. ### def process_input(): global trigger global lastval global in_pos global expected_val global begin global end if trigger: if (expected_val == in_data[in_pos]): end = datetime.now() lastval = in_data[in_pos] & 0xFF # calculate round trip time roundtrip_time = end - begin # here you could do something with the # measured value # reactivate the trigger for the next value trigger = False ### # This function is called every time a frame is about to be sent. # It contains the complete frame incl. all headers. The position of the # first data can be obtained via variable out_data_offset. ### def process_output(): global out_pos global trigger global out_data_offset global expected_val global begin pos = out_pos + out_data_offset new_val = out_data[pos] # if last value was received, create next value if not trigger: if (new_val != 0xFF) : new_val = new_val + 1 else: new_val = 0 begin = datetime.now() trigger = True # we always set the value in the process output out_data[pos] = new_val expected_val = new_val #pass ### # This function is called once the PNIO stack reports that # the connection is established. At this point in time, you can # retrieve the position of the individual data items as shown # below. ### def established(): global in_pos global out_pos # get the frame position of the first module, first submodule sub = config.getModulesToPlug().get(1).getAllSubmodules().get(0) in_pos = sub.getIoInputDataObject().getFrameOffset() # get the frame position of the second module, first submodule sub = config.getModulesToPlug().get(2).getAllSubmodules().get(0) out_pos = sub.getIoOutputDataObject().getFrameOffset() ### # This function is called once when the connection was closed. ### def closed(): pass ### # Called once during init of the script ### if __name__ == "__main__": pass

I&M

The I/M tab allows to read and write the I&M records 1-4.

To read a record, select the required record tab below the Record Commands and click on “Read I&Mx record”. To write a record, click on “Write I&Mx record”.

Alarms

The Alarms tab shows alarms generated by the device during a PROFINET connection. Alarms are shown in the Alarm List providing a timestamp when the alarm was received by the master and an Alarm Type. By clicking on an alarm entry, the details of the alarm are shown.

Per default, alarms are automatically acknowledged by the PROFINET Master. To disable automatic acknowledgement, untick the box “Auto ACK alarms” in the upper area of the Alarms tab.