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.
The I/O tab allows to setup and start a PROFINET RT I/O data connection.
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 variablein_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 |
---|---|---|---|
station_name | Name of the station the master is connected to |
| main |
mac | MAC address of the station the master is connected to | Byte Array | main |
config | Configuration of the PNIO connection. See description below |
| 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 |
| process_output |
A PnioConnectionConfig
object encapsulates the configuration of a PNIO connection. It provides the following functions:
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 |
getDataholdFactor | returns the data hold factor | data hold factor as |
getControllerReductionRatio | returns the controller reduction ratio | controller reduction ratio as |
Information of about individual modules is encode in PnioModule
and PnioSubmodule
instances.
A PnioModule
consists of the following functions:
Name | Description | Return value |
---|---|---|
getSlot | returns the slot where the module shall be plugged into | slot as |
getName | the name of the module | name as |
getInfoText | InfoText of the module | InfoText as |
getAllSubmodules | returns a list of submodules | list of |
A PnioSubmodule
provides of the following functions:
Name | Description | Return value |
---|---|---|
getName | returns the name of the submodule | name as |
getDirection | data direction of the submodule |
|
getInputSize | the size of input data in bytes | input data size as |
getOutputSize | the size of output data in bytes | output data size as |
getIoInputDataObject getIoOutputDataObject | returns an |
|
getSubslot | the subslot where the submodule shall be plugged into | subslot as |
getDeviceToControllerIoCsObject getControllerToDeviceIoCsObject | returns the cs |
|
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 |
---|---|---|
getFrameOffset | the offset of the data within a input frame ( | position as |
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.