Whats missing on this site?

  • Syntax currently only for DB acces
    • Markers
    • I/O
    • Timers, ...
  • We should have a complete list of all supported types and all plcs where they are available (see S7DataType from Chris).
  • We should cleary state all checks and inference the parser does

Address Syntax

The new Syntax has the following motivation

  • Be more familiar with the TIA Syntax well known by S7 programmers
  • Add Type Information to support all available TIA types
  • "Type inference" to be not too verbose

Supported types

BytesTIA NameSuitable Java EquivalentSupported S7 PLCs
1 bitBOOLbooleanall
1BYTEbyte[8]?all
1CHAR, SINTbyteall
1USINTshortall
2INTshortall
2WORDbyte[16]?all
2UNITintall
4DWORDbyte[32]?all
4DINTintall
4UDINTlongall
4REALfloatall
4TIME??
n+2STRING (equals STRING[254]) / STRING[n]Stringall


Syntax

Datablocks

Addressing is different for non-primitive and primitive types.

The general syntax for addressing primitive values in a Datablock is

%DB{db-number}.DB{bit-length-code}{byte-offset}(.{bit-offset})?
db-number: number of datablock
bit-length-code:
	X - 1 bit
	B - 8 bit / 1 byte
	W - 16 bit / 2 byte
	D - 32 bit / 4 byte
byte-offset: offset in byte to start of data block
bit-offset: offset in bit to start of bit

For non primitive objects the (pointer?) notation from TIA is used which is

P#DB{db-number}.DBX{byte-offset}.{bit-offset}
Note, here, bit offset is not optional but usually always 0

Type identifier Postfix

Primitives

Generally the TIA Syntax is used:

BOOL, INT, UINT, REAL

Furthermore the follwoing modifiers to the base types are used:

S = Short

D = Double

L = Long

Examples are:

SINT
USINT
DINT
LREAL
LINT
ULINTtax
Strings

Please see https://support.industry.siemens.com/tf/WW/en/posts/string-data-type/51621?page=0&pageSize=10

A short description of the syntax and intern format is found here , or here https://support.industry.siemens.com/cs/mdm/109755202?c=94063831435&lc=en-WW

The following Syntax is valid and will be supported:

STRING[n] // String with max number of characters: n
STRING // equivalent to STRING[254]

Note that a 2 byte prefix is used, so n+2 bytes have to be read from the plc.

The first byte represents the max length of the String, i.e., n above. The second one represents the actual length, i.e., the number of bytes to convert to string (starting from offset 2, then).

All bytes represent ASCII Chars.

String Syntax

I did not find any suitable information on how Strings are adressed, except that simple characters can be adressed similar to a byte array.

As it makes no sense at all to use a "width" identifier for the String, I suggest to use the syntax

%DB{block-id}.{byte-offset}:STRING[length]
%DB{block-id}.{byte-offset}:STRING

where the second version refers to the first version with length 254.

This Synatx is motivated by the Syntax which TIA uses e.g. for markers ("%M4.1") where there is only one kind of datatype.

Examples for valid addresses

%DB3.DX4.1
%DB3.DX4.1:BOOL
%DB3.DB4:INT
%DB3.DB4:UINT
%DB3.DW4:REAL

Special Data Areas: Markers, Inputs, Outputs

They are always adressed bit-wise and the syntax is similar to TIA.

// Marker
%M1.0 // byte 1, bit 0
%I0.5 // byte 0, bit 5
%Q1.1 // byte 1, bit 1

Additional Documents

Programming Guideline

https://w3.siemens.com/mcms/sce/de/fortbildungen/ausbildungsunterlagen/tia-portal/tabcardseiten/Documents/HW-Konfig-S7-1200/81318674_Programming_guideline_DOKU_v13_de.pdf

Addressing

https://support.industry.siemens.com/cs/mdm/109755202?c=69436189067&lc=en-WW

Data type

Absolute address

Example

Description

BOOL

%DBn.DBXx.y

%DB1.DBX1.0

Data bit 1.0 in DB1

BYTE, CHAR, SINT, USINT

%DBn.DBBy

%DB1.DBB1

Data bit 1 in DB1

WORD, INT, UINT

%DBn. DBWy

%DB1.DBW1

Data word 1 in DB1

DWORD, DINT, UDINT, REAL, TIME

%DBn.DBDy

%DB1.DBD1

Data double word 1 in DB1

More Absolut addressing

https://euroec.by/assets/files/weintek/plc_connection_guide/Siemens_S7_1200_S7_1500_absolute_addressing_Ethernet.pdf

Cheat Sheet

Direct Adressing Overview

http://www.multiprojekt.pl/ftp/weintek_hmi/plc_connection_guide/Siemens_S7_1200_S7_1500_absolute_addressing_Ethernet.pdf

  • No labels

7 Comments

  1. Unknown User (cdutz)

    I definitely +1 all these ... I like that you kept the bit-length-code as it does make things easier.

    Do I see it correctly, that you dropped your initial idea of making the bit-length-code optional? I like it as it does make things simpler.

    How should we handle invalid combinations, in this case?

    • %DB3.DW4.1:BOOL → Should probably result in an error as the 4 byte bit-length doesn't match the BOOL
    • %DB3.DW4.1:INT → Should probably result in an error as the bit-offset is only valid for boolean and 'X' bit-length

    And what are the types if the postfix type identifier is omitted? Do we simply take the smallest one that fits? ... but how can we decide between integer and floating-point with equal bit-length? Should this eventually not be optional, to keep both the code simple and avoid user-confusion?

    Especially for supporting the "L" Long options, we will need to find out the codes for these and we will have to define a S7 compatibility as not all S7 devices support all types.

    1. Julian Feinauer

      Hi Chris,

      this is currently "under development" and so a lot is missing still.

      To your questions:

      I dont know whose idea it whas to make the bit-length-code optional and why it was discussed but I totally agree with you that I dont like it, so full ack : )

      In my current implementation

      • %DB3.DW4.1:BOOL  throws an Exception as for type BOOL only identifier X is allowed
      • %DB3.DW4.1:INT throws an exception as bitOffset is only allowed for type BOOL

      both exceptions are thrown during parsing.

      The last question is trickier and is related to your Proposal 2.

      We had the idea to infer the type from the Java Return Type but this is no longer possible in the new "infrastructure".

      So we have three opinions

      1. Make a sensible default (i.e. Signed Integer), i.e. %DB3.DW4 is the same as %DB3.DW4:INT
      2. Keep the byte array in the ResponseItem and deserialize it as it is requested (infering the type from the getXXX method)
      3. Make it non-optional

      From a users perspective 2. is the nicest but in case of the getObject method that I like we can only throw a RuntimeException (which is bad, I think).

      Currently I would prefer option 1 or 3.


      Regarding the last note with the "L" options, I planned to create an S7 specifc type enum where I keep all type related information (transport size, transport code, data size, ...) in one place. There I would also keep the encoder / decoder which, with your comment should be something like Function1<S7DeviceType,Encoder>.

      I try to update the page today with all things written here.

      1. Unknown User (cdutz)

        How about making it not-optional for now and we can always make it optional in the future ... This would also make the implementation a lot simpler.


        Regarding the " S7 specifc type enum" ... that's already available ... just have a look at 

        org.apache.plc4x.java.s7.types.S7DataType

        Eventually we should just add missing types and add missing fields.

        1. Julian Feinauer

          Hey Chris, thats something I definetly missed. The Structure I created is basically equal with yours and has some more fields.

          I agree with you that we should merge those.

          It would be perfekt when you could shortly elaborate on the identifiers you use there (see my current questions on the mailing list).

          I do not (yet) fully get which identifier is tied to what and how many of these are there (transportsize, code, datatransport size, ...).

  2. Unknown User (cdutz)

    Regarding the datatypes I learnt yesterday, that the S7 devices handle them differently. So technically a WORD (16 bit) is equal to a SHORT (16 bit), but for the S7 a SHORT is a 16 bit integer number and a WORD is a set of 16 boolean values.

    1. Julian Feinauer

      Thanks for the hint, I didnt know that. I added this information.

  3. Unknown User (cdutz)

    It is not quite correct that Inputs and outputs are only accessed bitwise. I usually read all 8 digital inputs in a single byte ... and in larger S7 PLCs this could even go up to WORD or DWORD