Table of Contents
List of Tables
This manual is divided in six chapters (not counting this introduction). The first chapter introduces the concepts and features of the s7nodave device support for EPICS. The second chapter describes the few steps needed to start an IOC project making use of s7nodave. The third chapter describes the IOC shell commands supported by s7nodave. Subsequently, the fourth chapter explains the various record types supported by s7nodave. Finally, the fifth chapter explains how to use poll groups.
If you have used this software before and are upgrading to a newer version, you might find the appendix useful that describes the changes that have been made in recent version and how you might need to update your project to match these changes. been made compared
Warning | |
---|---|
When using this software to connect to a PLC, disconnect all external equipment from the PLC before trying to establish a connection. This software can overwrite variables in the PLC memory or even parts of the program running in the PLC. Therefore outputs of the PLC might show unpredictable behavior. There are a lot of different PLC types and depending on the type of the PLC, its configuration, the type of the host machine used for the EPICS IOC, the host machine's configuration and the EPICS IOC's configuration, this software might have very different, potentially unwanted results. It is always the responsibility of the user using this software to ensure, that its use is safe and complies with local regulation before connecting any equipment to the PLC. Violations of this rules might result in equipment being damaged or even persons being injured by misbehaving equipment. |
Table of Contents
This chapter introduces the concept of the s7nodave device support and the features offered by it.
The s7nodave device support is based on a slightly modified version of libnodave, originally created by Thomas Hergenhahn. This library implements the communication protocol supported by many PLCs from the S7 family and thus allows software on a PC to communicate with a PLC without having to explicitly implement communication routines on the PLC side.
Basically, s7nodave supports all PLCs supported by libnodave. However, as an additional constraint, the current version of libnodave only supports connections over Ethernet/PROFINET (ISO-TCP)and not over other kind of connections (e.g. special serial or USB adapters).
S7nodave has been developed using a S7-1200 PLC. However, there are reports that libnodave also works with S7-300, S7-400, and S7-1500 PLCs.
For new version of PLCs or TIA Portal, (in particular S7-1200 and S7-1500 series PLCs and TIA Portal version 12 and newer) the settings in the S7 project might have to be changed in order to allow full access to the PLCs memory. You might only be able to access global DBs and optimized block access for those DBs must be disabled. In addition to that, the access level must be set to full and the connection mechanism must allow GET/PUT communication. Please refer to the information available from the Snap7 project for a more detailed guide, including screenshots of the relevant configuration dialogs.
Important | |
---|---|
It is the responsibility of each user to verify, that the PLC being used is compatible with this software. The author of this software does not assume any liability regarding the compatibility of this software with a certain PLC or the eligibility for a certain application. |
The S7plc driver from PSI is based on a whole data-block being exchanged between the PLC and the EPICS IOC. This means, that it is not possible to write single records to the PLC. Instead, all values must be sent at once. The same applies to read requests. Besides, the structure of the data-block is coded into a PLC program. If a value is added or removed from the block, the addresses in the PLC logic as well as in the EPICS record configuration have to be updated.
The s7nodave device support on the other hand, directly reads from and writes to memory addresses in the PLC. The addresses configured in the EPICS records use the same notation that is used for programming the PLC logic. When an output record is process, on the value of this record is sent to the PLC. For input records, different records can be processed at different rates and only the values in the same poll group are transferred together.
S7nodave is implemented as an asynchronous device support based on asynDriver. While the asynDriver is used for configuration management, logging and asynchronous processing, neither the device support nor the low-level I/O routines supported by the asynDriver are used.
Table of Contents
This chapter describes the steps needed to setup a simple project using s7nodave. First, the prerequisites for using s7nodave are described. Subsequently, the installation and compilation of the s7nodave device support is explained. Finally, the steps needed to include the s7nodave device support in a project are shown.
S7nodave has three prerequisites: First,
EPICS base
R3.14.12 or higher is needed. Older versions of EPICS base might work
but in this case support for the aai
and
aao
record types must be disabled, because these
record types were broken in earlier versions of EPICS base.
In addition to that, the asynDriver is needed. S7nodave has been developed against version 4.13 of asyn, however most likely it also works with newer versions.
Finally, the Boost C++ library is needed (for compilation only, not at runtime). S7nodave has been developed using version 1.47.0 of Boost, but it should also work with newer versions, as long as the data structures of the optional, shared_ptr and string_algo libraries are not changed.
A modified version of libnodave is bundled with s7nodave and automatically compiled when s7nodave is compiled. Thus, you do not need to download or compile libnodave.
S7nodave has been developed under Linux, but should work on most POSIX-compliant operating systems. On Microsoft Windows, you will have to use a compatibility layer like Cygwin or change the network code in s7nodave to use the respective functions from the Windows API.
For compiling EPICS base and the asynDriver, refer to the respective manuals. Boost does not have to be compiled but can just be extracted to some directory on your disk.
After downloading s7nodave from the
project website,
extract it to the directory you want it to install in. A good place
might be the /opt/epics/modules
directory.
Subsequently, you have edit the configure/RELEASE
file in order to configure the locations where EPICS base, the
asynDriver and the Boost library are installed. Change the definitions
of ASYN
, RELEASE_INCLUDES
and
EPICS_BASE
to point to the right directories.
After editing this paths, you can run make to build s7nodave.
In the configure/RELEASE
file of your project, you
have to add a line like
S/NODAVE=/opt/epics/modules/s7nodave
. In the
Makefile
of the src
directory
of you application (e.g. myApp/src/Makefile
) you
have to add something like
my_DBD += s7nodave.dbd my_LIBS += s7nodave
in order to use the s7nodave device support in your record definition files.
Finally, you have to configure at least one PLC connection in the startup file of your IOC. See Section 4.1, “s7nodaveConfigureIsoTcpPort” for the syntax of the corresponding command. Optionally, you also might want to configure poll groups. For defining records that read from or write to the PLC, please refer to the record reference.
Table of Contents
S7nodave supports IOC shell commands for configuring a PLC connection and
for adding poll groups. In addition to
that, the
asyn commands
for configuring the trace mask and trace I/O mask are supported. However,
you have to add asyn.dbd
to the list of DBDs used
by your project in order to enable these commands in the IOC shell.
The s7nodaveConfigureIsoTcpPort
command is used to
setup a connection to a PLC and command has the
following syntax:
s7nodaveConfigureIsoTcpPort(PLC name, PLC hostname or IP address, PLC rack number, PLC slot number, thread priority)
The PLC name
is an arbitrary string, that is used to
refer to this PLC in the device address field of
records and when
configuring poll groups
for the PLC. However, the PLC name may not contain whitespace or
parentheses.
The PLC hostname or IP address
is the DNS hostname or
IP address of the PLC, optionally followed by the TCP port number
(separated from the hostname or IP address by a colon). If no port
number is specified, the default port (102) is used.
The PLC rack number
and
PLC slot number
depend on the actual PLC
configuration. For most setups, both numbers are zero, but rack 0,
slot 2 might have to be used with some S7-300 series PLCs. If you cannot
get access to the PLC, try to change those numbers. In case of doubt,
you should be able to find the correct numbers in the configuration of
your S7 project. You can find more information about rack and slot
numbers in the reference manual of the
Snap7 library.
The thread priority
is the priority used for the
communication thread (port thread in asyn nomenclature). If a priority
of 0
is specified, the priority
epicsThreadPriorityMedium
is used.
An example line configuring a connection to a PLC might look like this:
s7nodaveConfigureIsoTcpPort("myPLC", "myplc.example.com", 0, 0, 0)
You can have multiple instances of
s7nodaveConfigureIsoTcpPort
in your IOC startup
configuration, however the PLC name used must be unique for each
instance.
The s7nodaveConfigurePollGroup
command is used for
configuring poll groups and has the
following syntax:
s7nodaveConfigurePollGroup(PLC name, poll-group name, poll interval, thread priority)
The PLC name
must be the name of a PLC previously
used in an instance of
s7nodaveConfigureIsoTcpPort
.
The poll-group name
is an arbitrary string that
identifies the poll-group and must be unique for the PLC. However, the
same poll-group name may be used for two different PLCs. The poll-group
name must no contain whitespace, parentheses, the equal sign or commas.
The poll interval
is a floating point number that
specifies the interval in which the memory addresses belonging to the
poll group are read. The units of the poll interval are seconds.
The thread priority
specifies the priority of the
thread, that periodically processes the poll group. If a priority of
0
is specified, the priority
epicsThreadPriorityMedium
is used.
An example line configuring a poll group that is processed once a second might look like this:
s7nodaveConfigurePollGroup("myPLC", "1s", 1.0, 0)
You can have multiple instances of
s7nodaveConfigurePollGroup
per PLC, however the
poll-group name used must be unique for each instance referring to the
same PLC.
Table of Contents
In this chapter, first the format of the device addresses used for the s7nodave device support is explained. Subsequently the various PLC data-types supported by s7nodave are described. Finally, details about the records, supported by s7nodave, are given.
In order to use the s7nodave device address support for a record, the
record's device type field (DTYP
) has to specify
s7nodave
. This device type is used for all records
supported by s7nodave except the
waveform record.
The record's device address field (usually INP
for
input and OUT
for output records) must specify a
device address recognized by the s7nodave.
In general, a device address for s7nodave has the following format:
@PLC-name[(param1=value1,param2=value2,...)] PLC-address [PLC-data-type]
The exact supported options may vary depending on the record type.
Every device address start with the @
-sign, followed
by the PLC name. The PLC name must be the name of a PLC configured using
the
s7nodaveConfigureIsoTcpPort
statement in the IOC startup file.
The PLC name is followed by list of optional parameters wrapped in parentheses. If no parameters are given, the parentheses can be ommitted. The supported parameters depend on the record type. Please see Section 5.4, “Supported Parameters” and Section 5.5, “Supported Records” for details. If multiple parameters are specified, they are separated by commas.
The PLC memory address is separated from the PLC name (or the optional parameter list) by whitespace. Please refer to Section 5.2, “PLC Memory Addresses” for the the format of the PLC memory address.
Finally, an optional PLC data-type, which is separated from the PLC memory address by whitespace, can be specified. If no PLC data-type is specified, the data-type is guessed based on the record-type and PLC memory address. Please refer to Section 5.3, “PLC Data-Types” and Section 5.4, “Supported Parameters” for details about the supported PLC data-types.
Examples for valid device addresses:
@myPLC(DLV=0,DHV=27648) IW64
@myPLC(DLV=0,DHV=27648) IW66 int16
@myPLC IB0
@myPLC QB0
S7nodave uses the same format for PLC memory addresses, that is also usually used for programming the PLCs (e.g. using Step7 or WinPLC). The English and the German notation are both supported and equivalent to each other.
This format combines the specification of the start-byte of a variable in the PLC memory with specification of the variable's width.
The PLC address starts with the memory area. The following memory areas are supported:
Table 5.1. PLC Memory Areas
English | German | Description |
---|---|---|
DBn.DB | DBn.DB | Data Blocks (n must be an integer number) |
F | M | Flags |
I | E | Input Memory Image |
Q | A | Output Memory Image |
T | T | Timers |
C | Z | Counters |
For data block addresses the data-block number has to be included in the area specification. For addresses using the data-block, flags, input-memory and output memory areas, you next have to specify the width of the memory that should be read from or written to. The notation used for specifying the width is:
Table 5.2. PLC Memory Width
Notation | Description |
---|---|
X | Bit (only for DB areas, other areas use the empty string instead) |
B | Byte (8 bits) |
W | Word (16 bits) |
D | Double Word (32 bits) |
For addresses referring to a single bit (with the exception of bit addresses in DB areas) and for addresses referring to the counter or timer areas, no width specification is given: Bit addresses are identified by specifying the bit within the byte and the counter and timer areas always use word (16-bit) values.
After specifying the memory width, the start address must be specified.
The start address is always given in the number of bytes counted from
the beginning of the respective area (starting with zero). For example,
if at the beginning of DB1
two 32-bit numbers were
stored, the two addresses for these numbers would be
DB1.DBD0
and DB1.DBD4
.
For addresses referring to a single bit, the start bit within the byte
has to be specified, separated from the start byte by a dot. For
example, in order to refer to the first bit of the first byte in the
input-memory area, you would use the address I0.0
.
You must not specify a start bit for byte, word or double-word
addresses.
PLC memory-address specifications are not case-sensitive. However, for enhanced readability the use of upper case characters is recommended.
Examples for valid memory addresses:
DB3.DBD4
FW4
IB2
Q8.3
DB50.DBX17.3
T2
C2
s7nodave supports eight different PLC data-types. Each of these data-types may only be used together with a memory address having the right width:
Table 5.3. PLC Data Types and their Corresponding Memory Width
Data Type | Memory Width | Description |
---|---|---|
bool | 1 bit | Boolean |
int8 | Byte (8 bits) | Signed Integer |
uint8 | Byte (8 bits) | Unsigned Integer |
int16 | Word (16 bits) | Signed Integer |
uint16 | Word (16 bits) | Unsigned Integer |
int32 | Double Word (32 bits) | Signed Integer |
uint32 | Double Word (32 bits) | Unsigned Integer |
float | Double Word (32 bits) | Single Precision Floating Point Number |
The available data-types are also limited by the used record-type. Please refer to Section 5.5, “Supported Records” for details.
There is a number of optional parameters that can be used to specify device-support specific options for a record. Most of these options are only valid for a specific record-type, so please refer to the description of the respective options for finding out which option can be used with which record type.
The PG
parameter can be used with all input
records to specify a poll group
for the record. It is only valid, if the SCAN
field
of the record is set to I/O Intr
.
Example: @myPLC(PG=1s) IW64
The DLV
and DHV
parameters
specify the lower and upper bounds of the raw values read from or
written to the PLC. These values together with the record fields
EGUL
and EGUF
are used for
converting raw values to values in engineering units and vice-versa,
when the record's LINR
field is set to
LINEAR
.
If linear conversion is enabled, the conversion parameters are set
in such a way, that a raw value of DLV
corresponds
to an engineering units value of EGUL
and a raw
value of DHV
corresponds to an engineering units
value of EGUF
.
Please refer to the description of the
ai
and ao
records in the
EPICS Record Reference Manual
for details about linear conversion.
S7nodave supports most records from EPICS base, that have an interface
for device support routines. In order to use s7nodave with a record,
the record's DTYP
and INP
or
OUT
fields have to be set correctly. Please refer to
Section 5.1, “Device Address Format” for details. This
chapter describe the specific options for each supported record type.
This manual only describe those features of each record, which are specific to the s7nodave device support. Please refer to the EPICS Record Reference Manual for a general description of each record type and its fields.
The aai
record is used for reading multiple
elements from the PLC's memory into an array. The supported
PLC data-types depend on the EPICS data-type specified in the
record's FTVL
field, as described in this
table:
Table 5.4. Mapping of PLC Types to EPICS Types
bool | int8 | uint8 | int16 | uint16 | int32 | uint32 | float | |
---|---|---|---|---|---|---|---|---|
X = default for memory addresses of the corresponding width, o = supported, if specified explicitly | ||||||||
STRING | X | o | ||||||
CHAR | X | X | ||||||
UCHAR | X | X | ||||||
SHORT | X | X | o | X | ||||
USHORT | X | X | X | |||||
LONG | X | X | o | X | o | X | ||
ULONG | X | X | X | X | ||||
FLOAT | X | o | X | o | X | o | o | X |
DOUBLE | X | o | X | o | X | o | o | X |
ENUM | X | X | X |
For all EPICS data-types except STRING
, the width
of the PLC data-type has to match the width of the PLC address. In
this case, the total number of bytes read is the width of the PLC
data-type multiplied by the number of elements in the array. The PLC
memory address specified is the start of the first element in the
array.
If FTVL
is set to STRING
, the
PLC memory-address must be a byte. This byte is regarded to be the
first byte of the first string in the array. In total, fourty bytes
are read for each element in the array. For example, if the array has
ten elements, 400 bytes are read from the PLC memory.
If the PLC address specified refers to a bit, the number of bits read from the PLC equals the number of elements in the array. The read does not have to be aligned to byte boundaries.
The aao
record is used for writing multiple
elements from an array into the PLC's memory. The supported
PLC data-types depend on the EPICS data-type specified in the
record's FTVL
field, as described in this
table:
Table 5.5. Mapping of EPICS Types to PLC Types
bool | int8 | uint8 | int16 | uint16 | int32 | uint32 | float | |
---|---|---|---|---|---|---|---|---|
X = default for memory addresses of the corresponding width, o = supported, if specified explicitly | ||||||||
STRING | X | o | ||||||
CHAR | X | X | X | X | o | |||
UCHAR | X | X | o | X | o | X | o | |
SHORT | X | X | X | o | ||||
USHORT | X | X | o | X | o | |||
LONG | X | X | o | |||||
ULONG | X | X | o | |||||
FLOAT | X | o | o | o | o | o | o | X |
DOUBLE | X | o | o | o | o | o | o | X |
ENUM | X | X | o | X | o |
For all EPICS data-types except STRING
, the width
of the PLC data-type has to match the width of the PLC address. In
this case, the total number of bytes written is the width of the PLC
data-type multiplied by the number of elements in the array. The PLC
memory address specified is the start of the first element in the
array.
If FTVL
is set to STRING
, the
PLC memory-address must be a byte. This byte is regarded to be the
first byte of the first string in the array. In total, fourty bytes
are written for each element in the array. For example, if the array
has ten elements, 400 bytes are written to the PLC memory.
If the PLC address specified refers to a bit, the number of bits written to the PLC equals the number of elements in the array. The write does not have to be aligned to byte boundaries. Every non-zero number is converted to one before being written to the corresponding bit.
Writing a DOUBLE
value may be connected with loss
of precision, as the PLC driver only supports single precision
floating point numbers.
The ai
record is used for reading analog values
from the PLC. For conversion from PLC raw values to engineering units,
the DLV
and DVH
options can be
used (see Section 5.4.2, “DLV, DHV - Specifying Device Value Limits”).
The PLC data-types supported by this record are
bool
, int8
,
uint8
, int16
,
uint16
, int32
and
float
. When using the float
type, conversion from raw to engineering units is not supported.
The value from the PLC memory is directly written to the record's
VAL
field instead.
The ao
record is used for writing analog values to
the PLC. For conversion from engineering units to PLC raw units, the
DLV
and DHV
options can be used
(see Section 5.4.2, “DLV, DHV - Specifying Device Value Limits”).
The PLC data-types supported by this record are
bool
, int8
,
uint8
, int16
,
uint16
, int32
and
float
. When using the float
type, conversion from engineering to raw units is not supported.
The value of the record's VAL
field is written to
the PLC's memory instead. Please note that the conversion from
engineering to raw units might be lossy, if the calculated raw value
does not fit within the specificed PLC data-type.
The bi
record is used for reading a binary state
from the PLC. The PLC data-types supported by this record are
bool
, int8
,
uint8
, int16
,
uint16
, int32
,
uint32
and float
.
For all types except float
, a value that does not
equal zero is considered to be one. For float
s,
a value of NaN
or +inf
and
-inf
is also considered to be zero.
The bo
record is used to set a binary state in the
PLC. The PLC data-types supported by this record are
bool
, int8
,
uint8
, int16
,
uint16
, int32
,
uint32
and float
.
The longin
record is used for reading an integer
number from the PLC. The PLC data-types supported by this record are
bool
, int8
,
uint8
, int16
,
uint16
and int32
.
The longout
record is used for writing an integer
number to the PLC. The PLC data-types supported by this record are
bool
, int8
,
uint8
, int16
,
uint16
and int32
.
Please note that the write operation might be lossy, if the value written does not fit within the specificed PLC data-type.
The mbbi
and mbbiDirect
record
types are used for reading a state consisting of multiple bits from
the PLC. The PLC data-types supported by this record are
int8
, uint8
,
int16
, uint16
,
int32
and uint32
.
The SHFT
and NOBT
fields of the
record are supported by the s7nodave device support, so that bits
which are not aligned to the byte boundaries can be read.
As far as the s7nodave device support is concerned, there is no
difference between the mbbi
and
mbbiDirect
record-types. Please refer to the
EPICS Record Reference Manual
for the differences between the two record types.
The mbbo
and mbboDirect
record types are used for writing a state consisting of multiple bits
to the PLC. The PLC data-types supported by this record are
int8
, uint8
,
int16
, uint16
,
int32
and uint32
.
The SHFT
and NOBT
fields of the
record are supported by the s7nodave device support, so that bits
which are not aligned to the byte boundaries can be written. However,
the write operation is always applied to the complete byte, setting
the other bits to zero. If you want to set specific bits without
touching the other bits in the same byte, you should use the
bo or the
aao record.
As far as the s7nodave device support is concerned, there is no
difference between the mbbo
and
mbboDirect
record-types. Please refert to the
EPICS Record Reference Manual
for the differences between the two record types.
The stringin
record is used for reading a string
from the PLC. The PLC data-types supported by this record are
bool
, int8
and
uint8
.
If either the int8
(the default) or
uint8
data-type is specified, fourty bytes are
read from the PLC and interpreted as a string.
If the bool
data-type is specified, a single bit
is read from the PLC and the string is set to “TRUE” if the bit is one
and to “FALSE” if the bit is zero.
The stringout
record is used for writing a string
to the PLC. The PLC data-types supported by this record are
bool
, int8
and
uint8
.
If either the int8
(the default) or
uint8
data-type is specified, the fourty bytes of
the string stored in the record's VAL
field are
written to the PLC.
If the bool
data-type is specified, a single bit
is written to the PLC. If the string is “TRUE” or “1”, one is written,
otherwise zero is written.
The waveform
record is an alternative to the
aai and
aao records.
Unlike the other records, it can act as either an input or an output
record. The device address is always stored in the record's
INP
field. If you want to use the record as an
input record, you have to set the record's DTYP
field to s7nodaveWfIn
, if you want to use the
record as an output record, the field has to be set to
s7nodaveWfOut
. Apart from that, as far as the
s7nodave device support is concerned, this record acts exactly like
the aai
or aao
records.
Table of Contents
If you periodically scan multiple input records, that read data from the PLC, this is very inefficient, because each read operation sends a read request over the network and has to wait for a response from the PLC.
Thus, if multiple input records shall be processed at the same rate, you should put the in the same poll-group. The read request for all records being in the same poll group are placed in the same read request (unless the packet size is exceeded) and sent to the PLC together. Accordingly, the response from the PLC to all the read requests is also sent in a single packet, thus reducing the number of round-trips needed significantly.
Poll groups are only supported for input records, because output records typically are only processed on change anyway.
A poll group is created using the s7nodaveConfigurePollGroup command in the IOC's statup configuration. If you use the poll-group name “default”, this has a special meaning. This poll-group is used for all records, that are configured to use a poll group but do not explicitly specify the name of the poll group to use. For each PLC that is configured, the default poll-group must be configured separately.
In order to make a record be processed in a poll group, the
SCAN
field of the record has to be set to
I/O Intr
. If you want to use a different poll group
than the default poll-group, you can use the PG
parameter to specify the poll group to use (see
Section 5.4.1, “PG - Specifying a Poll Group”).
Table of Contents
Version 2.0.0 changed the parameter list of the s7nodaveConfigureIsoTcpPort command and changed the address format for individual bits in the DB area.
Two new parameters have been added to the s7nodaveConfigureIsoTcpPort command so that the PLC rack and slot number can be specified. This is necessary for some PLC configurations that do not use the default setting of rack 0 and slot 0 that was always assumed in older versions of this device support.
You will have to change existing IOC initialization scripts to include those two parameters. If older versions of s7nodave have worked for you, you can simply set both parameters to zero.
For example, if you have used the line
s7nodaveConfigureIsoTcpPort("myPLC", "myplc.example.com", 0)
you should now use
s7nodaveConfigureIsoTcpPort("myPLC", "myplc.example.com", 0, 0, 0)
.
Older versions of this device supported addressed individual bits in
DB areas using the format DBxx.DByy.z
.
Unfortunately, this format did not match the format used in other
software tools for the S7 PLC, which led to some confusion.
In version 2.0.0, the format has been changed to the widely used
format DBxx.DBXyy.z
. This means, that all
references to individual bits in DB areas have to be changed to match
the new format. This can simply be done by inserting the additional
X
after the second DB
term.
For example, the address DB20.DB10.4
has to be
changed to DB20.DBX10.4
.