# Siemens S7

> Relier des automates Siemens S7 par adresse en S7comm ou par nom de variable en S7CommPlus : le champ Accès, châssis et emplacement, zones de mémoire, adressage typé par octet et par bit, noms de variable, les réglages IHM et les types de donnée natifs.

Le pilote **Siemens S7** parle aux automates Siemens S7 en S7comm, le protocole
Step 7 classique porté par ISO-on-TCP. Il emploie l'adressage absolu (zone de
mémoire, numéro de bloc de données, octet et bit), si bien qu'il fonctionne sans aucun export de
symboles depuis le projet d'ingénierie. Ajoutez un équipement sous le pilote Siemens S7 dans le
[Connector](connector) et renseignez les champs ci-dessous ; le volet ne montre que les
champs que ce protocole emploie.

C'est l'accès **Par adresse**. Chaque équipement choisit son **Accès** : **Par adresse**,
comme ci-dessus, ou **Par nom** en S7CommPlus, le protocole qu'emploient TIA Portal et
les IHM Siemens, où chaque tag nomme sa variable comme TIA Portal l'écrit et où la CPU
dit son type.

## Accès {#access}

| Aspect | Par adresse | Par nom |
| --- | --- | --- |
| Protocole | S7comm sur ISO-on-TCP, port 102 | S7CommPlus sur TLS 1.3 dans ISO-on-TCP, port 102 |
| CPU | S7-300, S7-400, S7-1200, S7-1500 | S7-1500 en micrologiciel V2.9 ou ultérieur, S7-1200 en micrologiciel V4.5 ou ultérieur, configurées dans TIA Portal V17 ou ultérieur |
| Champs de l'équipement | Hôte, Châssis / Emplacement | Hôte, Nom d'utilisateur et Mot de passe, tous deux facultatifs |
| Ce qu'un tag nomme | Zone, numéro de DB, octet et bit, et son type de donnée | Le nom de la variable, par exemple `GanterOpt.Real_` ; la CPU dit le type |
| Sur la CPU | PUT/GET autorisé et blocs de données sans accès optimisé ([Préparer la CPU](#prepare-the-cpu)) | Rien à changer : les blocs de données optimisés se lisent, et PUT/GET n'est pas nécessaire |
| Découverte | Aucune | Les variables de la CPU ([Découverte](#discovery)) |

Un équipement créé maintenant démarre **Par nom**. Un équipement enregistré avant que ce
choix existe continue de lire **Par adresse**, comme il a toujours lu. Changer d'accès
garde à la fois les adresses typées des tags et les noms des variables, si bien que
revenir en arrière retrouve tout à sa place. Par nom, l'en-tête de l'équipement montre
l'endpoint sans châssis ni emplacement, par exemple
`s7://192.168.0.2?access=name`. Une CPU qui ne répond pas à l'accès par nom le dit sur
la page de l'équipement ([Une CPU sans l'accès par nom](#a-cpu-without-the-access-by-name)).

## Connexion {#connection}

| Champ | Sens | Défaut |
| --- | --- | --- |
| **Hôte** | L'adresse IP ou le nom d'hôte de la CPU (ou du module CP qui la précède). | vide |
| **Accès** | **Par adresse** ou **Par nom** ([Accès](#access)). | Par nom |
| **Châssis / Emplacement** | Par adresse seulement. Les numéros de châssis et d'emplacement de la CPU, tels que la configuration matérielle Siemens les définit. Deux zones de nombre sur une ligne : le châssis d'abord, l'emplacement ensuite. | 0 / 0 |
| **Nom d'utilisateur / Mot de passe** | Par nom seulement, tous deux facultatifs : le mot de passe de la protection de la CPU, quand son niveau d'accès en demande un, et un nom d'utilisateur seulement pour une CPU qui gère des utilisateurs. Enregistrés protégés sur cet ordinateur. | vide |
| **Intervalle de scrutation (ms)** | La période de lecture de tout l'équipement, pour les tags qui ne la remplacent pas. | 1 000 |

Le port TCP est fixé à 102 (ISO-on-TCP), il n'y a donc pas de champ de port. L'en-tête
de l'équipement montre l'endpoint assemblé, par exemple `s7://192.168.0.2:0:1`
(hôte, châssis, emplacement).

Le châssis et l'emplacement doivent correspondre au matériel : les CPU S7-1200 et S7-1500 répondent sur le
châssis 0, emplacement 0 ou 1 ; une CPU S7-300 typique se trouve au châssis 0, emplacement 2 ; les châssis S7-400
varient avec la configuration. Un mauvais emplacement fait échouer la connexion plutôt que de lire
de fausses données.

Chaque tag peut régler son propre **Intervalle de scrutation (ms)** ; une valeur de tag à 0 retombe sur
la période de l'équipement.

## Lire par nom {#read-by-name}

Un tag d'un équipement qui lit par nom nomme sa variable dans le champ **Nom de variable**
de la carte Source de la valeur, comme TIA Portal l'écrit : le bloc de données et la
variable, un point avant un membre, un élément de tableau entre crochets. Les guillemets
doubles de TIA Portal peuvent être saisis (`"GanterOpt".Real_`) et sont retirés.

| Variable dans TIA Portal | Nom de variable |
| --- | --- |
| `Real_` dans le bloc de données `GanterOpt` | `GanterOpt.Real_` |
| `Valor` de l'instance d'UDT `Udt_` | `GanterOpt.Udt_.Valor` |
| Élément 0 du tableau `Vetor` | `GanterOpt.Vetor[0]` |
| La DTL `DataHora` | `GanterOpt.DataHora` : un seul tag, une date et heure |

Il n'y a ni zone, ni numéro de DB, ni octet à saisir : la CPU dit où se trouve la
variable et de quel type elle est, et le pilote la lit comme le type de donnée du tag :

| Type dans la CPU | Type de donnée | Remarque |
| --- | --- | --- |
| Bool | Boolean | |
| Byte, USInt ; SInt | Byte ; SByte | Non signé ; signé |
| Word, UInt ; Int | UInt16 ; Int16 | Non signé ; signé |
| DWord, UDInt ; DInt | UInt32 ; Int32 | Non signé ; signé |
| LWord, ULInt ; LInt | UInt64 ; Int64 | Les 64 bits, exacts |
| Real ; LReal | Float ; Double | |
| Char, String | String | Windows-1252, comme par adresse |
| WChar, WString | String | UTF-16, toute écriture |
| Time, S5Time | Int32 | Millisecondes |
| LTime | Int64 | Nanosecondes |
| Time_Of_Day | UInt32 | Millisecondes depuis minuit, moins de 24 h |
| Date, Date_And_Time, DTL, LDT | DateTime | Date seule ; date et heure |

La découverte donne à chaque tag le type de donnée et l'unité (ms, ns) de sa variable.
Un tag créé à la main prend le type de donnée que vous choisissez, et la valeur de la
CPU y est convertie.

Une String ou une WString s'écrit en entier, à la longueur déclarée dans le bloc, que le
pilote lit sur la variable avant la première écriture : un texte plus long est refusé
avec les deux longueurs et rien n'est envoyé, et une String refuse un caractère hors de
Windows-1252. Une DTL se lit et s'écrit en entier, comme une date et heure ; ses huit
champs ne sont jamais proposés séparément, parce qu'un champ écrit seul accepte
n'importe quelle valeur (mois 90 compris). Une valeur hors de la plage de son type (un
Time_Of_Day de 24 h ou plus, 40000 pour un Int) est refusée avec la plage et rien n'est
envoyé. Un nom que la CPU n'a pas est l'erreur du tag et le dit ; un champ de DTL nommé
seul reçoit le conseil de nommer la DTL.

### Les réglages IHM {#the-hmi-settings}

TIA Portal tient trois réglages par variable d'un bloc de données, dans les colonnes du
bloc. La station les respecte comme le font l'IHM et le serveur OPC UA de Siemens, quoi
que la CPU laisse passer :

| Réglage dans TIA Portal | Quand il est décoché |
| --- | --- |
| **Accessible from HMI/OPC UA/Web API** | La variable n'est ni lue ni écrite : l'erreur du tag nomme le réglage, et la découverte la laisse de côté. |
| **Visible in HMI engineering** | La découverte laisse la variable de côté ; un tag qui la nomme à la main la lit normalement. |
| **Writable from HMI/OPC UA/Web API** | La variable est en lecture seule : une écriture est refusée en nommant le réglage, l'**Accès** du tag propose Lecture seule et dit pourquoi, et la découverte la propose en Lecture seule. |

### Une CPU sans l'accès par nom {#a-cpu-without-the-access-by-name}

Une CPU qui accepte la connexion et ne répond pas à l'accès par nom (une S7-1500 avant
le micrologiciel V2.9, une S7-1200 avant la V4.5, un projet configuré dans un TIA Portal
antérieur à la V17, ou une CPU qui ne parle que S7comm) laisse l'équipement hors ligne.
La page de l'équipement le dit dans un avis, à la place de l'erreur : ce dont la CPU a
besoin, où TIA Portal montre le micrologiciel (celui que la CPU exécute dans
**Online & diagnostics**, la version que nomme le projet dans les propriétés de la CPU,
sous **General > Catalog information**) et les trois issues :

1. Mettre à jour le micrologiciel de la CPU, régler la même version pour la CPU dans le
   projet TIA Portal et charger la configuration matérielle. Mettre à jour le
   micrologiciel seul ne suffit pas.
2. Mettre l'**Accès** sur **Par adresse**, avec PUT/GET autorisé et des blocs de données
   sans accès optimisé ([Préparer la CPU](#prepare-the-cpu)).
3. Lire la CPU par son propre serveur OPC UA (une S7-1500, ou une S7-1200 à partir du
   micrologiciel V4.4) avec le pilote [OPC UA](driver-opc-ua).

Chaque tag de l'équipement porte le même avis sur sa propre page, et l'avis disparaît de
lui-même dès que la CPU répond par nom. Le journal technique et l'agent lisent les mêmes
étapes dans l'erreur de l'équipement.

## Préparer la CPU {#prepare-the-cpu}

Cette section concerne l'accès par adresse ; un équipement qui lit par nom n'a besoin
d'aucun de ces réglages.

Une S7-1200 ou S7-1500 ne sert l'adressage absolu de S7comm qu'avec deux réglages qui lui sont propres, tous deux faits dans TIA Portal et chargés dans la CPU. Une S7-300 ou S7-400 n'a besoin d'aucun des deux.

| Réglage | Où dans TIA Portal | Sans lui |
| --- | --- | --- |
| **Permit access with PUT/GET communication from remote partner**, coché | Ouvrez la configuration des appareils de la CPU, sélectionnez la CPU, puis **Properties > General > Protection & Security > Connection mechanisms**. Chargez la configuration matérielle (**Download to device > Hardware configuration**) : un chargement du programme seul ne l'emporte pas. | La CPU accepte la connexion et refuse chaque lecture et chaque écriture. L'équipement reste connecté et ses tags se lisent en mauvaise qualité. |
| **Optimized block access**, décoché, sur chaque bloc de données que la station lit | Dans l'arborescence du projet, sous **Program blocks**, faites un clic droit sur le bloc de données, puis **Properties > General > Attributes**. Compilez le bloc et chargez-le. La colonne **Offset** du bloc montre alors où commence chaque variable, ce que prend l'**Octet de début** d'un tag. | La CPU ne sert aucun octet du bloc par adresse. Ses tags se lisent en mauvaise qualité, et les autres tags de l'équipement continuent de lire. |

Changer **Optimized block access** réinitialise le bloc de données au chargement : ses variables reviennent à leurs valeurs de départ. La mémoire de marqueurs (M), les entrées (I) et les sorties (Q) sont toujours adressables et ne demandent aucun changement. Un bloc de données qui doit rester optimisé peut se lire autrement : le programme de l'automate copie les valeurs que la station lit vers un bloc de données sans accès optimisé, ou vers la mémoire de marqueurs, et les tags y pointent ; ou la station lit l'automate par son propre serveur OPC UA (S7-1500 ; S7-1200 à partir du micrologiciel 4.4) avec le pilote [OPC UA](driver-opc-ua).

Quand la CPU refuse à cause de l'un ou l'autre réglage, la page de l'équipement dit lequel, avec ces étapes, dans un avis qui disparaît de lui-même dès que la CPU accepte. Pour un bloc de données, il nomme le bloc et les tags qu'il rend muets. Le journal technique et l'agent lisent les mêmes étapes. Un bloc de données que la CPU n'a pas, et une adresse au-delà de la fin d'un bloc de données, sont dits pour ce qu'ils sont sur le tag qui les nomme.

## Adressage {#addressing}

Cette section et les deux suivantes (Types de donnée, Écritures) concernent l'accès par
adresse ; l'accès par nom est dans [Lire par nom](#read-by-name).

Un tag S7 est adressé par des champs typés, pas par une chaîne en texte libre. Le volet
les montre dans la carte Source de la valeur du tag :

| Champ | Sens | Valeurs acceptées | Défaut |
| --- | --- | --- | --- |
| **Zone** | La zone de mémoire à lire. | `DataBlock`, `Merker`, `ProcessInput`, `ProcessOutput`, `Timer`, `Counter` | `DataBlock` |
| **Numéro de DB** | Quel bloc de données, affiché seulement quand la zone est `DataBlock`. | 0 et plus | 1 |
| **Octet de début** | Le décalage en octets, dans la zone, où la valeur commence. Dans les zones `Timer` et `Counter`, la zone s'intitule **Numéro de temporisation** ou **Numéro de compteur** et demande le numéro de la temporisation ou du compteur à la place. | 0 et plus | 0 |
| **Bit (0 à 7)** | La position du bit dans l'octet de début. Affiché seulement pour les tags booléens. | 0-7 | 0 |
| **Longueur maximale (vide = 254)** | Le maximum déclaré d'une STRING ou d'une WSTRING S7, en caractères. Affichée seulement pour les tags String hors des zones `Timer` et `Counter`. | 1-254 pour une STRING, 1-16382 pour une WSTRING, ou vide | vide |
| **Type de texte dans l'automate** | Le type sous lequel le texte est déclaré dans le bloc, à côté de sa longueur : `STRING` (un octet par caractère, Windows-1252) ou `WSTRING` (deux octets par caractère, UTF-16, toute écriture). Affiché là où figure la Longueur maximale. | `STRING`, `WSTRING` | `STRING` |

Les zones correspondent à la notation Siemens habituelle : `Merker` est la mémoire de marqueurs (M),
`ProcessInput` les entrées de l'image du procédé (I/E), `ProcessOutput` les
sorties de l'image du procédé (Q/A), et `Timer`/`Counter` les zones de temporisations et de compteurs
des CPU S7-300 et S7-400. Les temporisations et les compteurs s'adressent par numéro, pas par octet : `Timer` avec
le numéro 5 lit T5, et `Counter` avec le numéro 3 lit C3. Pour traduire les
adresses absolues classiques :

| Adresse classique | Type de donnée | Champs à saisir |
| --- | --- | --- |
| `DB5.DBD12` portant un REAL | Float | Zone `DataBlock`, numéro de DB 5, octet de début 12 |
| `DB1.DBX3.4` | Boolean | Zone `DataBlock`, numéro de DB 1, octet de début 3, bit 4 |
| `DB2.DBW20` portant un INT | Int16 | Zone `DataBlock`, numéro de DB 2, octet de début 20 |
| `MW10` | Int16 | Zone `Merker`, octet de début 10 |
| `M10.3` | Boolean | Zone `Merker`, octet de début 10, bit 3 |
| `IB2` | Byte | Zone `ProcessInput`, octet de début 2 |
| `Q4.1` | Boolean | Zone `ProcessOutput`, octet de début 4, bit 1 |
| `T5` | Int16 | Zone `Timer`, numéro de temporisation 5 |
| `C3` | Int16 | Zone `Counter`, numéro de compteur 3 |

Un tag booléen lit et écrit exactement un bit sur le bus ; il ne réécrit jamais
l'octet qui l'entoure. Tous les autres types sont adressés à l'octet de début avec
la largeur exacte de leur type de donnée. La ligne **Adresse source (bus)** en lecture seule de la
carte Source de la valeur montre l'adresse assemblée au fil de la saisie.

## Types de donnée {#data-types}

Le **Type de donnée** du tag décide du type S7 natif sur le bus. Les treize
largeurs natives S7 sont disponibles :

| Type de donnée | Type S7 | Taille sur le bus |
| --- | --- | --- |
| Boolean | BOOL | 1 bit |
| SByte | SINT | 1 octet |
| Byte | USINT | 1 octet |
| Int16 | INT | 2 octets |
| UInt16 | UINT | 2 octets |
| Int32 | DINT | 4 octets |
| UInt32 | UDINT | 4 octets |
| Int64 | LINT | 8 octets |
| UInt64 | ULINT | 8 octets |
| Float | REAL | 4 octets |
| Double | LREAL | 8 octets |
| String | STRING ou WSTRING | longueur maximale + 2 octets (STRING), longueur maximale × 2 + 4 octets (WSTRING) |
| DateTime | DTL | 12 octets |

Les valeurs sur plusieurs octets emploient automatiquement l'ordre gros-boutiste natif de S7 ; il
n'y a pas d'option d'ordre des octets parce qu'aucune n'est nécessaire.

Un tag String lit la disposition STRING S7 standard : un octet de maximum
déclaré, un octet de longueur courante, puis les caractères, un octet chacun en
Windows-1252, la page de code dans laquelle TIA Portal et les IHM Siemens affichent une STRING.
Ce que la station écrit est ce que TIA Portal et l'IHM affichent (« Peça 12 » reste
« Peça 12 »), et la station le relit à l'identique. La **longueur maximale** compte des
caractères et doit correspondre à la déclaration STRING du bloc (vide signifie le maximum S7 de
254) ; le pilote transfère longueur maximale + 2 octets par lecture. Un tag DateTime correspond
à la structure DTL de la famille S7-1200/1500 (de l'année aux nanosecondes) ;
l'ancien DATE_AND_TIME de 8 octets n'est pas proposé.

Un tag String dont le **Type de texte dans l'automate** est `WSTRING` lit à la place la disposition WSTRING S7 : un mot pour le maximum déclaré, un mot pour la longueur actuelle, puis les caractères, deux octets chacun en UTF-16, si bien qu'il accepte toute écriture ("中" est écrit et relu tel quel). La **Longueur maximale** compte toujours des caractères, de 1 à 16382, et doit correspondre à la déclaration WString du bloc (vide signifie 254, la longueur que TIA Portal donne à une WString déclarée sans longueur) ; le pilote transfère longueur maximale × 2 + 4 octets par lecture. S7comm ne peut pas lire le type dans la CPU, il doit donc correspondre à la variable : un tag laissé en `STRING` face à une variable WString lit et écrit la mauvaise disposition. Tout tag enregistré avant l'existence de ce champ est une `STRING`.

## Écritures {#writes}

Les tags dont l'**Accès** est Lecture et écriture ou Écriture seule peuvent être écrits. Les écritures
adressent la même zone, le même octet et le même bit que les lectures : une écriture booléenne pose son unique
bit, tout le reste écrit les octets exacts du type. Un nouveau tag démarre en
Lecture seule.

Une écriture String qui prend plus d'octets que la **Longueur maximale** est refusée et
rien n'est envoyé, jamais tronquée à la taille : le journal technique et l'agent lisent, par exemple,
"The DB1 byte 44 write was not sent: the text takes 21 bytes, and the STRING holds 20."
Un texte exactement aussi long que la **Longueur maximale** est écrit en entier.

Une écriture String qui contient un caractère hors de Windows-1252 (un caractère chinois, par
exemple) est refusée de la même façon, jamais écrite avec un point d'interrogation à sa place :
le journal technique et l'agent lisent, par exemple, "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." Le volet du tag donne la même raison dans la langue de la station.

Pour écrire un tel texte, déclarez la variable en WString dans le bloc et choisissez `WSTRING` dans le **Type de texte dans l'automate** du tag. Une WSTRING compte deux octets par caractère, et un texte plus long que sa **Longueur maximale** est refusé de la même façon, sans rien envoyer : "The DB1 byte 94 write was not sent: the text takes 42 bytes, and the WSTRING holds 40 (20 characters of two bytes)."

## Découverte {#discovery}

Une CPU lue par nom énumère ses variables ; S7comm n'en énumère aucune, et aucune
diffusion ne trouve une CPU. Sur la page du pilote, **CPU à balayer** dans la carte
**Portée du balayage** dit quelle CPU : un équipement Siemens du pilote qui lit sa CPU
par nom, balayé à l'hôte de cet équipement et connecté avec son mot de passe (la façon
dont une CPU protégée par mot de passe énumère ses variables), ou
**Une adresse saisie ici**, avec l'adresse de la CPU dans **Adresse de la CPU**.

**Découvrir** propose la CPU comme un équipement avec ses variables comme tags : celles
que la CPU marque accessibles et visibles depuis l'IHM, toutes cochées, avec le type que
dit la CPU, et en Lecture seule là où la CPU les marque non inscriptibles depuis l'IHM.
La liste est une arborescence par le chemin de chaque nom : le bloc de données, puis
chaque structure ou instance d'UDT et chaque tableau, puis les variables, chacune nommée
par la fin la plus courte de son nom qu'aucune autre variable ne partage (`Real_`,
`Valor`, `Vetor[0]`). Cocher une branche coche ou décoche tout ce qui est dessous, et la
branche dit combien de ses variables sont cochées ; une DTL est une seule variable.
**Ajouter un équipement** crée un équipement qui lit par nom avec les tags cochés.

Une CPU qu'un équipement Siemens de cette station lit déjà par nom est cet équipement,
quelle que soit la façon dont le balayage l'a nommée : le balayage se connecte avec le
mot de passe de cet équipement, et **Ajouter les tags** ajoute les variables pour
lesquelles il n'a pas encore de tag. Sur la page d'un équipement qui lit par nom,
**Découvrir les tags** dans la carte Tags fait la même chose pour ce seul équipement,
avec la même arborescence (voir [Découverte](connector-discovery#discovering-a-devices-tags)).
Un équipement qui lit par adresse ne propose pas Découvrir les tags : ajoutez ses tags à
la main.

## Bon à savoir {#good-to-know}

- Les zones Timer et Counter n'existent que sur les CPU S7-300 et S7-400. Un S7-1200
  n'a pas ces zones, et un S7-1500 les refuse par S7comm avec « Address out of range »
  même avec PUT/GET autorisé ; dans ce cas, copiez la valeur de la temporisation ou du
  compteur dans un bloc de données ou dans la mémoire de marqueurs depuis le programme
  de l'automate, et lisez-la à cet endroit. Là où les zones existent, elles s'adressent
  par numéro, pas par décalage en octets :
  la zone demande la temporisation ou le compteur lui-même (T0, T1, T2 et C0, C1, C2).
  Chaque valeur tient sur un mot de 16 bits, associez-la donc à Int16 ; un type de donnée
  plus large ou plus étroit est refusé, le tag étant nommé dans le journal technique, et les
  autres tags de l'équipement continuent de se lire.
- Un automate injoignable ne coûte rien au démarrage : l'équipement continue de réessayer en
  arrière-plan et ses tags se lisent en mauvaise qualité jusqu'à ce que la connexion s'établisse.
- Un câble débranché après que l'équipement est en ligne est remarqué à la lecture suivante :
  l'équipement passe hors ligne, ses tags passent en mauvaise qualité, et il se reconnecte de lui-même
  une fois le réseau revenu. Une adresse que la CPU refuse ne fait pas cela, si bien qu'un
  tag mal saisi n'emporte jamais le reste de l'équipement avec lui. Le tag dont la lecture a trouvé le lien coupé dit que la connexion à l'équipement a été perdue, dans la langue de la station, et la page Événements garde les mots de Sharp7.
