# Siemens S7

> Conectar PLC Siemens S7 por dirección sobre S7comm o por nombre de variable sobre S7CommPlus: el campo Acceso, rack y slot, áreas de memoria, direccionamiento tipado por byte y bit, nombres de variable, los ajustes de HMI y los tipos de dato nativos.

El driver **Siemens S7** habla con PLC Siemens S7 sobre S7comm, el protocolo clásico de
Step 7 transportado sobre ISO-on-TCP. Usa direccionamiento absoluto (área de memoria,
número de bloque de datos, byte y bit), así que funciona sin ninguna exportación de
símbolos del proyecto de ingeniería. Agregue un dispositivo bajo el driver Siemens S7
en el [Connector](connector) y llene los campos de abajo; el panel muestra solo los
campos que usa este protocolo.

Eso es el acceso **Por dirección**. Cada dispositivo elige su **Acceso**: **Por
dirección**, como arriba, o **Por nombre** sobre S7CommPlus, el protocolo que usan TIA
Portal y las HMI de Siemens, en el que cada tag nombra su variable tal como TIA Portal
la escribe y la CPU dice su tipo.

## Acceso {#access}

| Aspecto | Por dirección | Por nombre |
| --- | --- | --- |
| Protocolo | S7comm sobre ISO-on-TCP, puerto 102 | S7CommPlus sobre TLS 1.3 en ISO-on-TCP, puerto 102 |
| CPU | S7-300, S7-400, S7-1200, S7-1500 | S7-1500 con firmware V2.9 o posterior, S7-1200 con firmware V4.5 o posterior, configuradas en TIA Portal V17 o posterior |
| Campos del dispositivo | Host o IP, Bastidor / Ranura | Host o IP, Nombre de usuario y Contraseña, ambos opcionales |
| Lo que nombra un tag | Área, número de DB, byte y bit, y su tipo de dato | El nombre de la variable, por ejemplo `GanterOpt.Real_`; la CPU dice el tipo |
| En la CPU | PUT/GET permitido y bloques de datos sin acceso optimizado ([Preparar la CPU](#prepare-the-cpu)) | Nada que cambiar: los bloques de datos optimizados se leen, y PUT/GET no hace falta |
| Descubrimiento | Ninguno | Las variables de la CPU ([El descubrimiento](#discovery)) |

Un dispositivo creado ahora arranca **Por nombre**. Un dispositivo guardado antes de
que existiera esta elección sigue leyendo **Por dirección**, como siempre leyó. Cambiar
el acceso conserva tanto las direcciones tipadas de los tags como los nombres de las
variables, así que regresar al anterior lo encuentra todo donde estaba. Por nombre, el
encabezado del dispositivo muestra el endpoint sin rack ni slot, por ejemplo
`s7://192.168.0.2?access=name`. Una CPU que no contesta al acceso por nombre lo dice
en la página del dispositivo ([Una CPU sin el acceso por nombre](#a-cpu-without-the-access-by-name)).

## Conexión {#connection}

| Campo | Significado | Valor inicial |
| --- | --- | --- |
| **Host o IP** | Dirección IP o nombre de host de la CPU (o del módulo CP que la fronte). | vacío |
| **Acceso** | **Por dirección** o **Por nombre** ([Acceso](#access)). | Por nombre |
| **Bastidor / Ranura** | Solo por dirección. Los números de rack y de slot de la CPU, tal como están configurados en la disposición de hardware de Siemens. Dos cajas de número en una misma fila: primero el rack, después el slot. | 0 / 0 |
| **Nombre de usuario / Contraseña** | Solo por nombre, ambos opcionales: la contraseña de la protección de la CPU, cuando su nivel de acceso la pide, y un nombre de usuario solo en una CPU que administra usuarios. Se guardan protegidos en esta computadora. | vacío |
| **Intervalo de sondeo (ms)** | El periodo de lectura de todo el dispositivo, para los tags que no lo invaliden. | 1,000 |

El puerto TCP es fijo en 102 (ISO-on-TCP), así que no hay campo de puerto. El
encabezado del dispositivo muestra el endpoint armado, por ejemplo
`s7://192.168.0.2:0:1` (host, rack, slot).

El rack y el slot tienen que coincidir con el hardware: las CPU S7-1200 y S7-1500
contestan en el rack 0, slot 0 o 1; una CPU S7-300 típica está en el rack 0, slot 2;
los racks S7-400 varían según la disposición. Un slot equivocado hace fallar la
conexión en lugar de leer datos equivocados.

Cada tag puede poner su propio **Intervalo de sondeo (ms)**; un valor de 0 en el tag
cae en el intervalo del dispositivo.

## Leer por nombre {#read-by-name}

Un tag de un dispositivo que lee por nombre nombra su variable en el campo **Nombre de
variable** de la tarjeta Fuente, tal como TIA Portal la escribe: el bloque de datos y la
variable, un punto antes de un miembro, un elemento de un arreglo entre corchetes. Las
comillas dobles de TIA Portal se pueden escribir (`"GanterOpt".Real_`) y se quitan.

| Variable en TIA Portal | Nombre de variable |
| --- | --- |
| `Real_` en el bloque de datos `GanterOpt` | `GanterOpt.Real_` |
| `Valor` de la instancia de UDT `Udt_` | `GanterOpt.Udt_.Valor` |
| Elemento 0 del arreglo `Vetor` | `GanterOpt.Vetor[0]` |
| La DTL `DataHora` | `GanterOpt.DataHora`: un solo tag, una fecha y hora |

No hay área, número de DB ni byte que escribir: la CPU dice dónde está la variable y de
qué tipo es, y el driver la lee como el tipo de dato del tag:

| Tipo en la CPU | Tipo de dato | Nota |
| --- | --- | --- |
| Bool | Boolean | |
| Byte, USInt; SInt | Byte; SByte | Sin signo; con signo |
| Word, UInt; Int | UInt16; Int16 | Sin signo; con signo |
| DWord, UDInt; DInt | UInt32; Int32 | Sin signo; con signo |
| LWord, ULInt; LInt | UInt64; Int64 | Los 64 bits, exactos |
| Real; LReal | Float; Double | |
| Char, String | String | Windows-1252, como por dirección |
| WChar, WString | String | UTF-16, cualquier escritura |
| Time, S5Time | Int32 | Milisegundos |
| LTime | Int64 | Nanosegundos |
| Time_Of_Day | UInt32 | Milisegundos desde la medianoche, menos de 24 h |
| Date, Date_And_Time, DTL, LDT | DateTime | Solo la fecha; fecha y hora |

El descubrimiento le da a cada tag el tipo de dato y la unidad (ms, ns) de su variable.
Un tag creado a mano toma el tipo de dato que usted elija, y el valor de la CPU se
convierte a él.

Un String o un WString se escribe entero, con la longitud declarada en el bloque, que el
driver lee de la variable antes de la primera escritura: un texto más largo se rechaza
con las dos longitudes y no se envía nada, y un String rechaza un carácter fuera de
Windows-1252. Una DTL se lee y se escribe entera, como una fecha y hora; sus ocho campos
nunca se ofrecen por separado, porque un campo escrito solo acepta cualquier valor (mes
90 incluido). Un valor fuera del rango de su tipo (un Time_Of_Day de 24 h o más, 40000
para un Int) se rechaza con el rango y no se envía nada. Un nombre que la CPU no tiene es
el error del tag y lo dice; un campo de una DTL nombrado solo recibe el consejo de
nombrar la DTL.

### Los ajustes de HMI {#the-hmi-settings}

TIA Portal guarda tres ajustes por variable de un bloque de datos, en las columnas del
bloque. La estación los respeta como lo hacen la HMI y el servidor OPC UA de Siemens,
deje pasar la CPU lo que deje pasar:

| Ajuste en TIA Portal | Cuando está desmarcado |
| --- | --- |
| **Accessible from HMI/OPC UA/Web API** | La variable no se lee ni se escribe: el error del tag nombra el ajuste, y el descubrimiento la omite. |
| **Visible in HMI engineering** | El descubrimiento omite la variable; un tag que la nombra a mano la lee normalmente. |
| **Writable from HMI/OPC UA/Web API** | La variable es de solo lectura: una escritura se rechaza nombrando el ajuste, el **Acceso** del tag ofrece Solo lectura y dice por qué, y el descubrimiento la ofrece como Solo lectura. |

### Una CPU sin el acceso por nombre {#a-cpu-without-the-access-by-name}

Una CPU que acepta la conexión y no contesta al acceso por nombre (una S7-1500 anterior
al firmware V2.9, una S7-1200 anterior a la V4.5, un proyecto configurado en un TIA
Portal anterior a la V17, o una CPU que solo habla S7comm) deja el dispositivo sin
conexión. La página del dispositivo lo dice en un aviso, en lugar del error: lo que la
CPU necesita, dónde muestra TIA Portal el firmware (el que corre la CPU en
**Online & diagnostics**, la versión que nombra el proyecto en las propiedades de la
CPU, en **General > Catalog information**) y las tres salidas:

1. Actualizar el firmware de la CPU, poner la misma versión para la CPU en el proyecto
   de TIA Portal y cargar la configuración hardware. Actualizar solo el firmware no
   basta.
2. Poner el **Acceso** en **Por dirección**, con PUT/GET permitido y bloques de datos
   sin acceso optimizado ([Preparar la CPU](#prepare-the-cpu)).
3. Leer la CPU a través de su propio servidor OPC UA (una S7-1500, o una S7-1200 desde
   el firmware V4.4) con el driver [OPC UA](driver-opc-ua).

Cada tag del dispositivo lleva el mismo aviso en su propia página, y el aviso
desaparece solo en cuanto la CPU contesta por nombre. El diario técnico y el agente leen
los mismos pasos en el error del dispositivo.

## Preparar la CPU {#prepare-the-cpu}

Esta sección es del acceso por dirección; un dispositivo que lee por nombre no necesita
ninguno de estos ajustes.

Una S7-1200 o S7-1500 solo sirve el direccionamiento absoluto de S7comm con dos ajustes propios, ambos hechos en TIA Portal y cargados en la CPU. Una S7-300 o S7-400 no necesita ninguno.

| Ajuste | Dónde en TIA Portal | Sin él |
| --- | --- | --- |
| **Permit access with PUT/GET communication from remote partner**, marcado | Abra la configuración de dispositivos de la CPU, seleccione la CPU y luego **Properties > General > Protection & Security > Connection mechanisms**. Cargue la configuración hardware (**Download to device > Hardware configuration**): una carga solo del programa no lo lleva. | La CPU acepta la conexión y rechaza toda lectura y escritura. El dispositivo sigue conectado y sus tags se leen con mala calidad. |
| **Optimized block access**, desmarcado, en todo bloque de datos que la estación lea | En el árbol del proyecto, en **Program blocks**, haga clic con el botón derecho en el bloque de datos y luego **Properties > General > Attributes**. Compile el bloque y cárguelo. La columna **Offset** del bloque muestra entonces dónde empieza cada variable, que es lo que toma el **Byte inicial** de un tag. | La CPU no sirve ningún byte del bloque por dirección. Sus tags se leen con mala calidad, y los demás tags del dispositivo siguen leyendo. |

Cambiar **Optimized block access** reinicializa el bloque de datos en la carga: sus variables vuelven a sus valores iniciales. La memoria de marcas (M), las entradas (I) y las salidas (Q) siempre son direccionables y no necesitan cambios. Un bloque de datos que tiene que seguir optimizado puede leerse de otra manera: el programa del controlador copia los valores que lee la estación a un bloque de datos sin acceso optimizado, o a la memoria de marcas, y los tags apuntan ahí; o la estación lee el controlador a través de su propio servidor OPC UA (S7-1500; S7-1200 desde el firmware 4.4) con el driver [OPC UA](driver-opc-ua).

Cuando la CPU rechaza por cualquiera de los dos ajustes, la página del dispositivo dice cuál, con estos pasos, en un aviso que desaparece solo en cuanto la CPU acepta. Para un bloque de datos nombra el bloque y los tags que deja sin lectura. El diario técnico y el agente leen los mismos pasos. Un bloque de datos que la CPU no tiene, y una dirección más allá del final de un bloque de datos, se dicen como lo que son en el tag que los nombra.

## El direccionamiento {#addressing}

Esta sección y las dos siguientes (Los tipos de dato, Las escrituras) son del acceso por
dirección; el acceso por nombre está en [Leer por nombre](#read-by-name).

Un tag de S7 se direcciona con campos tipados, no con una cadena de texto libre. El
panel los muestra en la tarjeta Fuente del tag:

| Campo | Significado | Valores aceptados | Valor inicial |
| --- | --- | --- | --- |
| **Área** | El área de memoria que se lee. | `DataBlock`, `Merker`, `ProcessInput`, `ProcessOutput`, `Timer`, `Counter` | `DataBlock` |
| **Número de DB** | Qué bloque de datos, mostrado solo cuando el Área es `DataBlock`. | 0 en adelante | 1 |
| **Byte inicial** | El desplazamiento en bytes dentro del área donde empieza el valor. En las áreas `Timer` y `Counter` la caja se rotula **Número de temporizador** o **Número de contador** y pide el número del temporizador o del contador en su lugar. | 0 en adelante | 0 |
| **Bit (0 a 7)** | La posición del bit dentro del byte inicial. Se muestra solo en los tags booleanos. | de 0 a 7 | 0 |
| **Longitud máxima (en blanco = 254)** | El máximo declarado de un STRING o WSTRING de S7, en caracteres. Se muestra solo en los tags String fuera de las áreas `Timer` y `Counter`. | de 1 a 254 en un STRING, de 1 a 16382 en un WSTRING, o en blanco | en blanco |
| **Tipo de texto en el controlador** | El tipo con el que el texto está declarado en el bloque, junto a su longitud: `STRING` (un byte por carácter, Windows-1252) o `WSTRING` (dos bytes por carácter, UTF-16, cualquier escritura). Se muestra donde aparece la Longitud máxima. | `STRING`, `WSTRING` | `STRING` |

Las áreas corresponden a la notación habitual de Siemens: `Merker` es la memoria de
marcas (M), `ProcessInput` las entradas de la imagen de proceso (I/E), `ProcessOutput`
las salidas de la imagen de proceso (Q/A), y `Timer`/`Counter` las áreas de
temporizadores y contadores de las CPU S7-300 y S7-400. Los temporizadores y los contadores se direccionan
por número, no por byte: `Timer` con el número 5 lee T5, y `Counter` con el número 3
lee C3. Traduciendo las direcciones absolutas clásicas:

| Dirección clásica | Tipo de dato | Campos que hay que llenar |
| --- | --- | --- |
| `DB5.DBD12` con un REAL | Float | Área `DataBlock`, Número de DB 5, Byte inicial 12 |
| `DB1.DBX3.4` | Boolean | Área `DataBlock`, Número de DB 1, Byte inicial 3, Bit 4 |
| `DB2.DBW20` con un INT | Int16 | Área `DataBlock`, Número de DB 2, Byte inicial 20 |
| `MW10` | Int16 | Área `Merker`, Byte inicial 10 |
| `M10.3` | Boolean | Área `Merker`, Byte inicial 10, Bit 3 |
| `IB2` | Byte | Área `ProcessInput`, Byte inicial 2 |
| `Q4.1` | Boolean | Área `ProcessOutput`, Byte inicial 4, Bit 1 |
| `T5` | Int16 | Área `Timer`, Número de temporizador 5 |
| `C3` | Int16 | Área `Counter`, Número de contador 3 |

Un tag booleano lee y escribe exactamente un bit en el bus; nunca reescribe el byte que
lo rodea. Todos los demás tipos se direccionan por byte en el byte inicial, con el
ancho exacto de su tipo de dato. La línea de solo lectura **Dirección de origen (bus)**
de la tarjeta Fuente muestra la dirección armada conforme usted edita.

## Los tipos de dato {#data-types}

El **Tipo de dato** del tag decide el tipo nativo de S7 que va en el bus. Están
disponibles los trece anchos nativos de S7:

| Tipo de dato | Tipo de S7 | Tamaño en el bus |
| --- | --- | --- |
| 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 o WSTRING | longitud máxima + 2 bytes (STRING), longitud máxima × 2 + 4 bytes (WSTRING) |
| DateTime | DTL | 12 bytes |

Los valores de varios bytes usan automáticamente el orden de bytes big-endian nativo de
S7; no hay opción de orden de bytes porque no hace falta ninguna.

Un tag String lee la disposición estándar de un STRING de S7: un byte con el máximo
declarado, un byte con la longitud actual, y luego los caracteres, un byte cada uno en
Windows-1252, la página de códigos en la que TIA Portal y las HMI de Siemens muestran un
STRING. Lo que la estación escribe es lo que TIA Portal y la HMI muestran ("Peça 12" sigue
siendo "Peça 12"), y la estación lo vuelve a leer igual. La **Longitud máxima** cuenta
caracteres y tiene que coincidir con la declaración del STRING en el bloque (en blanco
significa el máximo de S7, 254); el driver transfiere la longitud máxima más 2 bytes por
lectura. Un tag DateTime corresponde a la estructura DTL de la familia S7-1200/1500 (del
año a los nanosegundos); el DATE_AND_TIME antiguo, de 8 bytes, no se ofrece.

Un tag String cuyo **Tipo de texto en el controlador** es `WSTRING` lee en cambio la disposición WSTRING de S7: una palabra con el máximo declarado, una palabra con la longitud actual, y luego los caracteres, dos bytes cada uno en UTF-16, así que admite cualquier escritura ("中" se escribe y se vuelve a leer como "中"). La **Longitud máxima** sigue contando caracteres, de 1 a 16382, y tiene que coincidir con la declaración WString del bloque (en blanco significa 254, la longitud que TIA Portal le da a un WString declarado sin ella); el driver transfiere la longitud máxima × 2 + 4 bytes por lectura. S7comm no puede leer el tipo en la CPU, así que tiene que coincidir con la variable: un tag que se queda en `STRING` frente a una variable WString lee y escribe con la disposición equivocada. Todo tag guardado antes de que existiera el campo es un `STRING`.

## Las escrituras {#writes}

Los tags cuyo **Acceso** es Lectura y escritura o Solo escritura se pueden escribir.
Las escrituras direccionan la misma área, el mismo byte y el mismo bit que las lecturas:
una escritura booleana pone su único bit, y todo lo demás escribe los bytes exactos del
tipo. Un tag nuevo arranca como Solo lectura.

Una escritura String que ocupa más bytes que la **Longitud máxima** se rechaza y no se
envía nada, nunca se recorta al tamaño: el diario técnico y el agente leen, por ejemplo, "The
DB1 byte 44 write was not sent: the text takes 21 bytes, and the STRING holds 20." Un
texto exactamente tan largo como la **Longitud máxima** se escribe completo.

Una escritura String con un carácter fuera de Windows-1252 (un carácter chino, por ejemplo) se
rechaza de la misma forma, nunca se escribe con un signo de interrogación en su lugar: el
diario técnico y el agente leen, por ejemplo, "The DB1 byte 44 write was not sent: the STRING
holds Windows-1252 characters only, and '中' (U+4E2D) is not one of them; it fits once the tag's text type in the PLC and the PLC variable are both WSTRING." El panel del tag da el mismo motivo en el idioma de la estación.

Para escribir un texto así, declare la variable como WString en el bloque y elija `WSTRING` en el **Tipo de texto en el controlador** del tag. Un WSTRING cuenta dos bytes por carácter, así que un texto más largo que su **Longitud máxima** se rechaza de la misma forma, sin enviar nada: "The DB1 byte 94 write was not sent: the text takes 42 bytes, and the WSTRING holds 40 (20 characters of two bytes)."

## El descubrimiento {#discovery}

Una CPU leída por nombre enumera sus variables; S7comm no enumera ninguna, y ninguna
difusión encuentra una CPU. En la página del driver, **CPU que escanear** en la tarjeta
**Alcance del escaneo** dice qué CPU: un dispositivo Siemens del driver que lee su CPU
por nombre, escaneado en el host de ese dispositivo y entrando con su contraseña (la
forma en que una CPU protegida con contraseña enumera sus variables), o
**Una dirección escrita aquí**, con la dirección de la CPU en **Dirección de la CPU**.

**Descubrir** ofrece la CPU como un dispositivo con sus variables como tags: las que la
CPU marca como accesibles y visibles desde la HMI, todas marcadas, con el tipo que dice
la CPU, y de Solo lectura donde la CPU las marca como no escribibles desde la HMI. La
lista es un árbol por la ruta de cada nombre: el bloque de datos, luego cada struct o
instancia de UDT y cada arreglo, luego las variables, cada una nombrada por el final más
corto de su nombre que ninguna otra variable comparte (`Real_`, `Valor`, `Vetor[0]`).
Marcar una rama marca o desmarca todo lo que hay abajo, y la rama dice cuántas de sus
variables están marcadas; una DTL es una sola variable. **Agregar dispositivo** crea un
dispositivo que lee por nombre con los tags marcados.

Una CPU que un dispositivo Siemens de esta estación ya lee por nombre es ese
dispositivo, como sea que el escaneo la haya nombrado: el escaneo entra con la
contraseña de ese dispositivo, y **Agregar tags** agrega las variables para las que
todavía no tiene tag. En la página de un dispositivo que lee por nombre,
**Descubrir tags** en la tarjeta Tags hace lo mismo solo para ese dispositivo, con el
mismo árbol (vea [El descubrimiento](connector-discovery#discovering-a-devices-tags)).
Un dispositivo que lee por dirección no ofrece Descubrir tags: agregue sus tags a mano.

## Bueno saber {#good-to-know}

- Las áreas Timer y Counter solo existen en las CPU S7-300 y S7-400. Un S7-1200 no
  tiene esas áreas, y un S7-1500 las rechaza por S7comm con "Address out of range"
  aunque PUT/GET esté permitido; en ese caso, copie el valor del temporizador o del
  contador a un bloque de datos o a la memoria de marcas desde el programa del PLC y
  léalo de ahí. Donde las áreas existen, se direccionan por número, no por
  desplazamiento de byte:
  la caja pide el temporizador o el contador mismo (T0, T1, T2 y C0, C1, C2). Cada
  valor es una palabra de 16 bits, así que empárejelo con Int16; un tipo de dato más
  ancho o más angosto se rechaza, con el tag nombrado en el diario técnico, y los demás
  tags del dispositivo siguen leyendo.
- Un PLC inalcanzable no cuesta nada al arrancar: el dispositivo sigue reintentando en
  segundo plano y sus tags se leen con mala calidad hasta que la conexión llega.
- Un cable jalado después de que el dispositivo está en línea se nota en la siguiente
  lectura: el dispositivo se va sin conexión, sus tags pasan a mala calidad, y se
  reconecta solo en cuanto la red regresa. Una dirección que la CPU rechaza no hace
  eso, así que un tag mal escrito nunca se lleva consigo al resto del dispositivo. El tag cuya lectura encontró el enlace caído dice que se perdió la conexión con el dispositivo, en el idioma de la estación, y la página Eventos guarda las palabras de Sharp7.
