# Siemens S7

> Connect Siemens S7 PLCs over S7comm - rack and slot, memory areas, typed byte/bit addressing and the native data types.

The **Siemens S7** driver talks to Siemens S7 PLCs over S7comm, the classic
Step 7 protocol carried on ISO-on-TCP. It uses absolute addressing — memory
area, data-block number, byte and bit — so it works without any symbol export
from the engineering project. Add a device under the Siemens S7 driver in the
[Connector](connector) and fill in the fields below; the panel shows only the
fields this protocol uses.

## Connection {#connection}

| Field | Meaning | Default |
| --- | --- | --- |
| **Host** | IP address or host name of the CPU (or of the CP module that fronts it). | empty |
| **Rack / Slot** | The CPU's rack and slot numbers, as configured in the Siemens hardware layout. Two number boxes on one row: rack first, slot second. | 0 / 0 |
| **Poll interval (ms)** | Device-wide read period for tags that do not override it. | 1,000 |

The TCP port is fixed at 102 (ISO-on-TCP), so there is no port field. The
device header shows the assembled endpoint, for example `s7://192.168.0.2:0:1`
(host, rack, slot).

Rack and slot must match the hardware: S7-1200 and S7-1500 CPUs answer on
rack 0, slot 0 or 1; a typical S7-300 CPU sits at rack 0, slot 2; S7-400 racks
vary with the layout. A wrong slot fails the connection rather than reading
wrong data.

Each tag may set its own **Poll interval (ms)**; a tag value of 0 falls back to
the device interval.

## Addressing {#addressing}

An S7 tag is addressed by typed fields, not by a free-text string. The panel
shows them in the tag's Source card:

| Field | Meaning | Accepted values | Default |
| --- | --- | --- | --- |
| **Area** | The memory area to read. | `DataBlock`, `Merker`, `ProcessInput`, `ProcessOutput`, `Timer`, `Counter` | `DataBlock` |
| **DB number** | Which data block, shown only when Area is `DataBlock`. | 0 and up | 1 |
| **Start byte** | Byte offset inside the area where the value starts. In the `Timer` and `Counter` areas the box is labelled **Timer number** or **Counter number** and asks for the number of the timer or counter instead. | 0 and up | 0 |
| **Bit (0–7)** | Bit position inside the start byte. Shown only for Boolean tags. | 0–7 | 0 |
| **Max length (blank = 254)** | Declared maximum of an S7 STRING. Shown only for String tags outside the `Timer` and `Counter` areas. | 1 and up, blank | blank |

The areas map to the usual Siemens notation: `Merker` is flag memory (M),
`ProcessInput` the process-image inputs (I/E), `ProcessOutput` the
process-image outputs (Q/A), and `Timer`/`Counter` the S7 timer and counter
areas. Timers and counters are addressed by number, not by byte: `Timer` with
the number 5 reads T5, and `Counter` with the number 3 reads C3. Translating
classic absolute addresses:

| Classic address | Data type | Fields to enter |
| --- | --- | --- |
| `DB5.DBD12` holding a REAL | Float | Area `DataBlock`, DB number 5, Start byte 12 |
| `DB1.DBX3.4` | Boolean | Area `DataBlock`, DB number 1, Start byte 3, Bit 4 |
| `DB2.DBW20` holding an INT | Int16 | Area `DataBlock`, DB number 2, Start byte 20 |
| `MW10` | Int16 | Area `Merker`, Start byte 10 |
| `M10.3` | Boolean | Area `Merker`, Start byte 10, Bit 3 |
| `IB2` | Byte | Area `ProcessInput`, Start byte 2 |
| `Q4.1` | Boolean | Area `ProcessOutput`, Start byte 4, Bit 1 |
| `T5` | Int16 | Area `Timer`, Timer number 5 |
| `C3` | Int16 | Area `Counter`, Counter number 3 |

A Boolean tag reads and writes exactly one bit on the wire; it never rewrites
the surrounding byte. Every other type is byte-addressed at the start byte with
the exact width of its data type. The Source card's read-only **Source address
(wire)** line shows the assembled address as you edit.

## Data types {#data-types}

The tag's **Data type** decides the S7 native type on the wire. All thirteen
S7-native widths are available:

| Data type | S7 type | Size on the wire |
| --- | --- | --- |
| Boolean | BOOL | 1 bit |
| SByte | SINT | 1 byte |
| Byte | USINT | 1 byte |
| Int16 | INT | 2 bytes |
| UInt16 | UINT | 2 bytes |
| Int32 | DINT | 4 bytes |
| UInt32 | UDINT | 4 bytes |
| Int64 | LINT | 8 bytes |
| UInt64 | ULINT | 8 bytes |
| Float | REAL | 4 bytes |
| Double | LREAL | 8 bytes |
| String | STRING | max length + 2 bytes |
| DateTime | DTL | 12 bytes |

Multi-byte values use the S7-native big-endian byte order automatically; there
is no byte-order option because none is needed.

A String tag reads the standard S7 STRING layout: one byte of declared
maximum, one byte of current length, then ASCII characters. **Max length**
must match the STRING declaration in the block (blank means the S7 maximum of
254); the driver transfers max length + 2 bytes per read. A DateTime tag maps
to the DTL structure of the S7-1200/1500 family (year through nanoseconds);
the older 8-byte DATE_AND_TIME is not offered.

## Writes {#writes}

Tags whose **Access** is Read and write or Write only can be written. Writes
address the same area, byte and bit as reads: a Boolean write sets its single
bit, everything else writes the type's exact bytes. A new tag starts as
Read only.

## Discovery {#discovery}

S7comm has no broadcast discovery, so the Connector shows no Discover button
for this driver. Add the device and its tags by hand.

## Good to know {#good-to-know}

- On S7-1200/1500 CPUs, S7comm's absolute addressing requires two settings in
  the Siemens project: **Permit access with PUT/GET communication** on the CPU,
  and **optimized block access switched off** on every data block you address.
  An optimized DB has no byte offsets to address.
- The Timer and Counter areas are addressed by number, not by byte offset:
  the box asks for the timer or counter itself (T0, T1, T2 and C0, C1, C2).
  Each value is one 16-bit word, so pair it with Int16; a wider or narrower
  data type is refused with the tag named in the journal, and the device's
  other tags keep reading.
- An unreachable PLC costs nothing at startup: the device keeps retrying in
  the background and its tags read as bad quality until the connection lands.
- A cable pulled after the device is online is noticed on the next read: the
  device goes offline, its tags turn bad quality, and it reconnects on its own
  once the network is back. An address the CPU refuses does not do that, so one
  mistyped tag never takes the rest of the device down with it.
