Chapter 1. Introduction

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.

Chapter 2. Concept

This chapter introduces the concept of the s7nodave device support and
the features offered by it.

2.1. libnodave

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.

2.2. Supported Devices

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.

2.3. Communication between the PLC and EPICS

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.

2.4. Integration into EPICS

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.

Chapter 3. Getting Started

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.

3.1. Prerequisites

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.

3.2. Compiling the Prerequisites

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.

3.3. Compiling s7nodave

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.

3.4. Using s7nodave in a project

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.

Chapter 4. IOC Shell Reference

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.

4.1. s7nodaveConfigureIsoTcpPort

The s7nodaveConfigureIsoTcpPort command is used to
setup a connection to a PLC and command has the
following syntax:

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.

4.2. s7nodaveConfigurePollGroup

The s7nodaveConfigurePollGroup command is used for
configuring poll groups and has the
following syntax:

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.

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.

5.1. Device Address Format

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.

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

5.2. PLC Memory Addresses

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

5.3. PLC Data-Types

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:

5.4. Supported Parameters

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.

5.4.1. PG - Specifying a Poll Group

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

5.4.2. DLV, DHV - Specifying Device Value Limits

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.

5.5. Supported Records

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.

5.5.1. aai - Array Input

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:

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.

5.5.2. aao - Array Output

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:

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 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 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.

5.5.5. bi - Binary Input

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 floats,
a value of NaN or +inf and
-inf is also considered to be zero.

5.5.6. bo - Binary Output

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.

5.5.7. longin - Long Input

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.

5.5.8. longout - Long Output

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.

5.5.9. mbbi, mbbiDirect - Multi-Bit Binary Input

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.

5.5.10. mbbo, mbboDirect - Multi-Bit Binary Output

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.

5.5.11. stringin - String Input

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.

5.5.12. stringout - String Output

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.

5.5.13. waveform - Array Input or Output

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.

Chapter 6. Poll Groups

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.

6.1. Creating a Poll Group

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.

6.2. Including a Record in a Poll Group

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”).

A.1. What's new in s7nodave 2.0

Version 2.0.0 changed the parameter list of the
s7nodaveConfigureIsoTcpPort
command and changed the address format for individual bits in the DB area.

A.1.1. New Parameters for the s7nodaveConfigureIsoTcpPort Command

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).

A.1.2. Changed Address Format for Bit Addresses in DB Areas

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.