DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
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
| Bytes | TIA Name | Suitable Java Equivalent | Supported S7 PLCs |
|---|---|---|---|
| 1 bit | BOOL | boolean | all |
| 1 | BYTE | byte[8]? | all |
| 1 | CHAR, SINT | byte | all |
| 1 | USINT | short | all |
| 2 | INT | short | all |
| 2 | WORD | byte[16]? | all |
| 2 | UNIT | int | all |
| 4 | DWORD | byte[32]? | all |
| 4 | DINT | int | all |
| 4 | UDINT | long | all |
| 4 | REAL | float | all |
| 4 | TIME | ? | ? |
| n+2 | STRING (equals STRING[254]) / STRING[n] | String | all |
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
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 |

7 Comments
Unknown User (cdutz)
Aug 27, 2018I 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-lengthAnd 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.Julian Feinauer
Aug 27, 2018Hi 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 BOOLboth 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
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.
Unknown User (cdutz)
Aug 27, 2018How 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
Eventually we should just add missing types and add missing fields.
Julian Feinauer
Sep 02, 2018Hey 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, ...).
Unknown User (cdutz)
Sep 04, 2018Regarding 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.
Julian Feinauer
Sep 04, 2018Thanks for the hint, I didnt know that. I added this information.
Unknown User (cdutz)
Sep 04, 2018It 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