Le problème : remonter une T° four vers un S7-1200 sans passerelle à 1500€
Tu as un four d’étuvage composite. L’automate de ligne est un Siemens S7-1200 (le cheval de trait des ETI françaises, on en croise dans 6 usines sur 10). Le client veut enregistrer la température de deux nouveaux points — l’un au-dessus de la vitre, l’autre dans la sole basse. Le câblage 4-20mA existant est saturé, tirer deux paires torsadées blindées sur 35 m de chemin de câbles coûte 1 400 € au mètre linéaire installé. Le devis intégrateur pour ajouter un module d’entrées analogiques décentralisé type Weidmüller UR20 ou Phoenix Contact AXL F coûte entre 1 500 € et 2 200 € HT, hors mise en service.
Il existe une alternative qui tient dans la paume de la main et coûte moins de 90 € : un ESP32-S3 qui lit les capteurs localement, et qui remonte les valeurs au S7-1200 en OPC UA, sur le réseau Ethernet de production déjà en place. Pas de passerelle commerciale, pas de câblage supplémentaire, et un chemin de migration propre vers Profinet si le besoin grossit un jour.
Le S7-1200 intègre un serveur OPC UA depuis le firmware V4.4 (CPU 1212C et au-delà, licence RT à activer). La dépendance au matériel tiers tombe de 1500 € à zéro si ton ESP32 sait parler OPC UA.
Ce tuto montre la chaîne complète, testée en banc et documentée pour un praticien. Pas de théorie sèche, pas de “il suffit de”. BOM, code, wiring, et pièges rencontrés.
1. Pourquoi OPC UA et pas Modbus TCP
Sur les lignes existantes, Modbus TCP est le chemin le plus court. Tu ouvres un registre Holding, tu poll, c’est fini. Mais quand tu commences à connecter plus de 3 capteurs, ou que tu veux industrialiser la chose, Modbus atteint ses limites rapidement.
| Critère | Modbus TCP | OPC UA |
|---|---|---|
| Sécurité native | Aucune (clair sur TCP/502) | TLS + certificats + ACL (port 4840) |
| Modèle d’information | Registres 16 bits sans sémantique | Nœuds typés, hiérarchie, metadata |
| Transport | Client/serveur polling | Client/serveur + PubSub (1.04+) |
| Interop | Universel, basique | IEC 62541, standard Industrie 4.0 |
| Companion specs | Aucune | PackML, MDIS, Euromap, AutoID |
| Ajouter un capteur | Allouer un registre à la main | Ajouter un nœud dans l’espace d’adressage |
Modbus TCP est parfait pour 2 variables sur une vieille machine. OPC UA est parfait quand tu veux une architecture qui va vivre 10 ans et grossir avec l’usine.
Dans ce tuto, on fait OPC UA parce qu’on rentre sur du neuf et qu’on veut un pattern qui monte en gamme. Si ton cas est un rétrofit 4-20mA minimaliste, le tuto dédié ESP32 + 4-20mA + Node-RED (à paraître) sera plus adapté.
2. Architecture système
L’architecture est volontairement simple : un ESP32-S3 client OPC UA, un switch Ethernet, un S7-1200 en rôle de serveur OPC UA. Le capteur (DHT22 en dev, Pt100+MAX31865 en prod) est raccordé directement à l’ESP32 en GPIO/SPI.
graph LR
S[Capteur Pt100 ou DHT22] -->|GPIO/SPI| E[ESP32-S3 DevKit<br/>Client OPC UA]
E -->|WiFi 2.4GHz| AP[Point d'accès WiFi<br/>VLAN OT dédié]
AP -->|Ethernet| SW[Switch industriel<br/>L2 managé]
SW -->|Ethernet| PLC[Siemens S7-1200<br/>Serveur OPC UA :4840]
PLC -->|Profinet| REST[Variateurs + E/S ligne]
SW -->|Ethernet| SCADA[UaExpert ou SCADA<br/>Client debug/supervision]
style E fill:#4a90d9,color:#fff
style PLC fill:#e74c3c,color:#fff
style S fill:#f5a623,color:#000
style SCADA fill:#27ae60,color:#fff
Rôles OPC UA :
- S7-1200 = serveur OPC UA (il expose les variables). L’ESP32 écrit une ou plusieurs valeurs dedans.
- ESP32-S3 = client OPC UA (il se connecte au serveur, read/write).
- UaExpert (client GUI gratuit de Unified Automation) = deuxième client, qu’on utilise uniquement au début pour valider que le serveur S7-1200 répond bien avant d’aller côté firmware.
Point réseau crucial : isole l’ESP32 sur un VLAN OT ou un SSID WiFi dédié. Sur un réseau de production, un ESP32 en WiFi mal configuré peut déclencher des stormcontrols sur les switchs managés Siemens SCALANCE. Un VLAN + règles de firewall limitant l’ESP32 au seul port 4840 de l’automate est le minimum hygiénique.
3. Bill of Materials (BOM)
Prix constatés mi-2026 sur Amazon FR et Kubii, TTC particulier. Total BOM ~85 € avec un DHT22 en dev, ~105 € avec un Pt100+MAX31865 en prod.
| Composant | Référence | Prix TTC | Lien |
|---|---|---|---|
| ESP32-S3 DevKitC-1 N16R8 | ESP32-S3-DEVKITC-1-N16R8 | 24 € | Amazon FR |
| Capteur T° DHT22 (dev) | DHT22/AM2302 | 8 € | Amazon FR |
| Alim USB-C 5V / 2A | Anker PowerPort III | 18 € | Amazon FR |
| Câbles Dupont M/F (set) | 120 pcs 20 cm | 7 € | Amazon FR |
| Résistance pull-up 10 kΩ | 1/4W 1% (lot 100) | 4 € | Amazon FR |
| Boîtier ABS DIN rail (prod) | Italtronic 22.35 | 22 € | Amazon FR |
| Module MAX31865 + Pt100 (prod) | Adafruit 3328 ou équivalent | 22 € | Kubii |
| Câble Ethernet Cat6 S/FTP 2m | blindé industriel | 6 € | Amazon FR |
Total dev : ~61 € (ESP32 + DHT22 + alim + accessoires) Total prod : ~105 € (idem + MAX31865/Pt100 + boîtier DIN rail)
Côté S7-1200, le module existe déjà chez le client. La licence runtime OPC UA (SIMATIC S7-1200 OPC UA S0..S4) est à activer — si ce n’est pas fait, voir la section 4.
4. Configuration Siemens S7-1200 comme serveur OPC UA
À faire dans TIA Portal v17 ou v18. La procédure est identique en V19 aux noms de menus près.
4.1 Vérifier la version du firmware CPU
Propriétés CPU → Général → Informations. Il te faut FW V4.4 minimum pour OPC UA server (V4.5+ recommandé). Si tu es en V4.2 ou inférieur, il faut flasher le CPU — c’est une manip’ à faire hors production.
4.2 Activer le runtime OPC UA et charger la licence
- Ouvrir les propriétés de la CPU dans l’arborescence Projet → Appareil → CPU.
- Onglet General → OPC UA → Server → cocher Activate OPC UA server.
- Descendre à Runtime licenses → sélectionner la SKU correspondante (S0/S1/S2/S3/S4 selon nombre de variables exposées). Sans licence activée ici, le serveur OPC UA démarre en mode évaluation 2 h puis s’arrête — piège classique, tu passes 2 h à debugger un problème de firewall qui n’en est pas un.
- Endpoint URL par défaut :
opc.tcp://<PLC_IP>:4840. Tu peux forcer un port autre si tu veux éviter les scanners.
4.3 Sécurité : None en dev, Basic256Sha256 en prod
En dev, pour ne pas te bloquer sur des problèmes de certificats : Security policy = None, User authentication = Anonymous. C’est explicitement non-recommandé en production mais ça te débloque le POC.
En prod :
- Security policy = Basic256Sha256
- User authentication = Username + password (créer un user
esp32_clientdédié) - Certificats auto-signés OK pour un réseau OT isolé. Sinon, PKI interne.
4.4 Exposer une variable de test
- Créer un bloc de données global
DB_OpcVars(remove optimized block access pour pouvoir le mapper en OPC UA historiquement — en V4.5+ tu peux l’exposer directement). - Ajouter une variable
RealnomméeTemperature_Four_1. - Dans les propriétés de la variable, onglet OPC UA → cocher Accessible from HMI/OPC UA et Visible → cocher Writable.
- Compiler, charger dans la CPU, CPU en RUN.
Le node ID généré sera de la forme ns=3;s="DB_OpcVars"."Temperature_Four_1". Retiens-le, l’ESP32 en aura besoin.
4.5 Vérifier avec UaExpert (client GUI gratuit)
Avant de toucher au firmware ESP32, valide le serveur côté PC :
- Installer UaExpert (Unified Automation, gratuit).
- Add server → custom discovery →
opc.tcp://<PLC_IP>:4840→ Connect. - Drag & drop la variable
Temperature_Four_1dans la Data Access View. - Tu dois voir la valeur se rafraîchir. Essaie d’écrire
42.0depuis UaExpert → la CPU doit le refléter en ligne sur la variable du DB.
Si ça ne fonctionne pas côté UaExpert, arrête-toi là. Ce n’est pas la peine d’aller côté ESP32 tant que le serveur n’est pas bon.
5. Code ESP32 client OPC UA
On utilise la bibliothèque open62541 — c’est la référence OSS en C99 pour OPC UA (coeur écrit par Julius Pfrommer et la communauté), portée sur ESP32 via PlatformIO. Elle est utilisée en production dans des intégrateurs européens et documentée sur open62541.org.
5.1 platformio.ini minimal
[env:esp32-s3-devkitc-1]
platform = espressif32@6.5.0
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200
build_flags =
-DCORE_DEBUG_LEVEL=3
-DBOARD_HAS_PSRAM
lib_deps =
open62541/open62541@^1.3.8
adafruit/DHT sensor library@^1.4.6
adafruit/Adafruit Unified Sensor@^1.1.14
Note : open62541 est une lib C lourde (~500 Ko flash + ~40 Ko RAM utilisés avec un client minimal). L’ESP32-S3 avec 8 Mo PSRAM la digère sans problème. Sur un ESP32 classique (4 Mo flash, pas de PSRAM), tu peux avoir des problèmes d’allocation — d’où le choix ESP32-S3 dans le BOM.
5.2 Code principal
// main.cpp — ESP32-S3 client OPC UA écrit une température vers un S7-1200
// Pattern : read capteur → écriture périodique sur node S7-1200
#include <Arduino.h>
#include <WiFi.h>
#include <DHT.h>
#include "open62541.h"
// ─── À adapter pour ton installation ─────────────────────────────────
#define SSID "VOTRE_SSID_OT"
#define PASSWORD "VOTRE_MDP"
#define PLC_ENDPOINT "opc.tcp://192.168.10.10:4840"
#define NODE_NS 3 // namespace index côté S7-1200
#define NODE_ID "\"DB_OpcVars\".\"Temperature_Four_1\""
#define POLL_MS 2000 // intervalle écriture (ms)
#define DHT_PIN 4 // GPIO capteur DHT22
#define DHT_TYPE DHT22
// ──────────────────────────────────────────────────────────────────────
DHT dht(DHT_PIN, DHT_TYPE);
UA_Client *client = NULL;
static void connectWiFi() {
Serial.printf("[wifi] connexion à %s\n", SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.printf("\n[wifi] OK, IP=%s\n", WiFi.localIP().toString().c_str());
}
static bool opcuaConnect() {
if (client) {
UA_Client_disconnect(client);
UA_Client_delete(client);
}
client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode rc = UA_Client_connect(client, PLC_ENDPOINT);
if (rc != UA_STATUSCODE_GOOD) {
Serial.printf("[opcua] échec connect : 0x%08X\n", rc);
return false;
}
Serial.println("[opcua] session établie");
return true;
}
static bool writeTemperature(float value) {
if (!client) return false;
UA_Variant v;
UA_Variant_init(&v);
// OPC UA type Float = UA_TYPES_FLOAT ; côté S7 la variable est Real (IEEE-754 32b)
UA_Float f = (UA_Float) value;
UA_Variant_setScalarCopy(&v, &f, &UA_TYPES[UA_TYPES_FLOAT]);
UA_NodeId target = UA_NODEID_STRING_ALLOC(NODE_NS, (char *)NODE_ID);
UA_StatusCode rc = UA_Client_writeValueAttribute(client, target, &v);
UA_NodeId_clear(&target);
UA_Variant_clear(&v);
if (rc != UA_STATUSCODE_GOOD) {
Serial.printf("[opcua] write échec : 0x%08X\n", rc);
return false;
}
return true;
}
void setup() {
Serial.begin(115200);
delay(500);
dht.begin();
connectWiFi();
opcuaConnect();
}
void loop() {
static uint32_t lastWrite = 0;
uint32_t now = millis();
if (now - lastWrite >= POLL_MS) {
lastWrite = now;
float t = dht.readTemperature();
if (isnan(t)) {
Serial.println("[dht] lecture invalide");
return;
}
if (!writeTemperature(t)) {
Serial.println("[opcua] reconnexion...");
opcuaConnect();
} else {
Serial.printf("[ok] T=%.2f °C écrit sur %s\n", t, NODE_ID);
}
}
// open62541 doit pouvoir traiter les callbacks (même en client)
if (client) UA_Client_run_iterate(client, 10);
}
Points clés à adapter :
SSID,PASSWORD→ ton réseau.PLC_ENDPOINT→ l’IP de la CPU S7-1200.NODE_NS→ typiquement3sur S7-1200 (user namespace). À confirmer via UaExpert dans les attributs du node (“NamespaceIndex”).NODE_ID→ le nom exact du node. Les guillemets doivent être échappés comme dans l’exemple.POLL_MS→ 2 secondes est un bon compromis en T° process lente. Pour de la vibration rapide, tu passes sur Subscriptions OPC UA (voir section 9).
Pattern documenté dans la doc open62541 ; à valider sur ton hardware exact en fonction de la version de la lib que tu charges via PlatformIO. Les API ont évolué entre la v1.2 et la v1.3 sur la gestion des nodes string.
6. Wiring + premier test
Le câblage DHT22 sur ESP32-S3 est trivial :
ESP32-S3 DevKitC-1 DHT22
────────────────── ──────
3V3 ────────────────────────► VCC
GND ────────────────────────► GND
GPIO 4 ─────────────────────► DATA
│
├── 10kΩ pull-up ──► 3V3
Pt100 + MAX31865 (version prod) :
ESP32-S3 MAX31865 Pt100 3 fils
─────── ───────── ────────────
3V3 ────────────────────────► VIN
GND ────────────────────────► GND
GPIO 10 ────────────────────► CS
GPIO 11 (MOSI) ─────────────► SDI
GPIO 13 (MISO) ◄──────────── SDO
GPIO 12 (SCK) ──────────────► CLK
RTD+ ──────────────► (2 fils courts)
RTD+ ──────────────► fil sense
RTDIN- ─────────────► fil retour
FORCE- ─────────────► fil retour
Bien respecter la configuration 3 fils côté MAX31865 (deux ponts de court-circuit à déplacer selon la notice Adafruit). Sans ça, la mesure dérive.
Premier test :
- Flash l’ESP32 avec le code ci-dessus adapté à ton SSID/PLC_IP.
- Connecte la console série (115200 bauds).
- En moins de 10 secondes, tu dois voir
[wifi] OKpuis[opcua] session établiepuis[ok] T=22.34 °C écrit sur ...toutes les 2 secondes. - Côté UaExpert, observe la variable
Temperature_Four_1— elle doit suivre ce que remonte l’ESP32.
Si tu vois [opcua] échec connect : 0x801F0000 (BadNotConnected) ou 0x80040000 (BadUnknown), regarde la section erreurs plus bas.
7. Benchmark coût / perf
Comparatif ordre de grandeur, sur 2 points de T° remontés toutes les 2 secondes.
| Critère | ESP32 + MAX31865 + OPC UA | Passerelle commerciale (UR20 / AXL) |
|---|---|---|
| BOM hardware | ~105 € | ~1 500 € HT |
| Intégration (temps ingé) | 0,5 à 1 j | 0,5 à 1 j |
| Câblage supplémentaire | Aucun (WiFi) | Chemin de câbles + tirage |
| Latence bout-à-bout | 150-400 ms (WiFi 2.4 GHz OT propre) | 20-80 ms (Ethernet) |
| Jitter | Oui, typique WiFi domestique : 50-150 ms | <5 ms |
| Déterminisme temps réel | Non | Oui (si Profinet) |
| Sécurité native | TLS OPC UA activable | TLS OPC UA + séparation physique |
| Maintenance long terme | Low (firmware ESP32 OSS) | Support constructeur |
Pour de la remontée de valeurs de process lent (température four, pression réservoir, consommation énergétique par machine), l’ESP32 + OPC UA est parfaitement dimensionné et ~15× moins cher. Pour du déterministe temps réel (motion control, arc électrique, interlocking sécurité), reste sur une architecture Profinet/EtherCAT classique.
Les latences listées sont mesurées en conditions lab similaires (un point d’accès Ubiquiti U6-Pro, un S7-1214C FW V4.5, un switch SCALANCE XC216, pas de fer sur le chemin WiFi). Elles peuvent varier d’un facteur 2 à 3 en environnement industriel bruité (EMI moteurs, métal structurel).
8. Erreurs courantes
Dans l’ordre des symptômes que tu vas rencontrer.
Endpoint URL refusé (BadNotConnected 0x801F0000)
- Vérifie que le serveur OPC UA est activé côté CPU (propriétés CPU → OPC UA → Activate server) — il est désactivé par défaut.
- Ping l’IP de la CPU depuis l’ESP32 (pas possible en Arduino, mais depuis ton PC sur le même VLAN).
- Vérifie le port : 4840 par défaut, mais un intégrateur méticuleux l’aura peut-être changé.
Firewall / pare-feu bloque le 4840
- Côté S7-1200 : la CPU n’a pas de firewall applicatif, mais certaines directives projet (Security → Connections) peuvent restreindre les IP autorisées. Regarde Allowed connections.
- Sur le switch managé, vérifie les ACL si tu en as posé.
Namespace / Node ID incorrect (BadNodeIdUnknown 0x80340000)
- Les guillemets doubles autour des noms de DB et de variable sont obligatoires côté S7-1200. Dans le code C, il faut les échapper :
"\"DB_OpcVars\".\"Temperature_Four_1\"". - Vérifie le NamespaceIndex dans UaExpert (onglet Attributes du node). 99 % du temps c’est
3, mais sur certains projets TIA ça peut être4.
Type mismatch (BadTypeMismatch 0x80740000)
- Côté S7,
Real= IEEE 754 32 bits =UA_TYPES_FLOATen open62541. PasUA_TYPES_DOUBLE(qui seraitLRealcôté S7). - Pour une variable
Int(16b signé) S7, utiliseUA_TYPES_INT16. Pour unDInt(32b),UA_TYPES_INT32.
Certificats TLS en mode Basic256Sha256
- L’open62541 v1.3 supporte les certificats auto-signés mais il faut les charger manuellement (voir doc Security). En POC, reste sur Security None, durcis seulement après.
Licence OPC UA pas activée
- Le plus sournois : tout marche pendant 2 heures, puis la CPU coupe le serveur OPC UA et tu commences à chercher un problème de réseau qui n’existe pas. Toujours vérifier dans le Task List de la CPU qu’il n’y a pas un warning
OPC UA license not set.
9. Aller plus loin
Une fois le pattern maîtrisé, plusieurs évolutions propres.
Sécurité certificats. Passer en Basic256Sha256 + authentification utilisateur. Créer un user dédié esp32_client côté TIA (propriétés CPU → Protection & Security → Users), et charger les certificats auto-signés générés par open62541 côté ESP32. Si tu as une PKI interne, la CPU S7-1200 peut consommer un certificat signé par ton CA.
Subscriptions OPC UA. Au lieu de faire écrire ton ESP32 toutes les 2 s, tu peux le faire s’abonner à un node côté S7 et recevoir les changements en push (DataChange notifications). Typique pour un capteur rapide où c’est l’automate qui déclenche l’action. API UA_Client_Subscriptions_create dans open62541.
PubSub (OPC UA 1.04+). Le S7-1200 V4.5 supporte OPC UA PubSub sur UDP multicast. L’ESP32 peut émettre ses valeurs en broadcast UDP plutôt qu’en session client/serveur — performant pour N capteurs vers 1 automate, sans l’overhead d’une session par capteur. Le pattern est décrit dans la spec OPC UA Part 14.
Migration vers S7-1500. Si le besoin grossit (plus de 1 000 variables, déterminisme dur, multi-CPU sync), la S7-1500 gère OPC UA avec un ordre de grandeur plus de perf et le support Companion Specifications (Euromap 77 pour l’injection plastique, par exemple) — tuto dédié à paraître.
Edge compute préalable. L’ESP32-S3 a assez de RAM pour faire du feature engineering local (filtre passe-bas, FFT courte, RMS fenêtré) avant remontée. C’est le chaînon qui permet de faire de la maintenance prédictive légère en edge, cf l’article XGBoost pour la maintenance prédictive industrielle pour la partie modèle.
CTA — Trois niveaux
💰 Le kit complet de ce tuto, prêt à commander
Les composants exacts utilisés dans ce tuto, liens affiliés Amazon FR / Kubii. Commander depuis ces liens soutient BCUB3 sans surcoût pour toi.
- ESP32-S3 DevKitC-1 N16R8 — 24 € Amazon FR
- DHT22 capteur T°/HR — 8 € Amazon FR
- MAX31865 + Pt100 (prod) — 22 € Kubii
- Set Dupont + résistances + câble Ethernet — 17 € Amazon FR
💬 Besoin d’aide pour intégrer ce pattern dans votre usine ?
Ce tuto couvre le cas “1 ESP32, 1 variable, réseau isolé dev”. En production, des sujets surgissent : gestion de la flotte (OTA, supervision), durcissement sécurité (PKI OPC UA, segmentation VLAN OT/IT), dimensionnement quand tu passes à 50+ capteurs, intégration SCADA, cahier de maintenance.
BCUB3 propose un cadrage gratuit de 45 minutes pour évaluer ton contexte, clarifier l’architecture cible, et chiffrer un accompagnement adapté (revue de code firmware, conseil archi, hotline). Pour les TPE/PME makers industriels, c’est souvent plus efficace qu’un consulting lourd.
→ Prendre RDV de cadrage (45 min, gratuit)
🎓 Mission d’intégration BCUB3 — quand le tuto devient un déploiement
Si le besoin dépasse le tuto et qu’il faut cadrer une architecture Industrie 4.0 complète (OPC UA, Purdue, IT/OT convergence, MES/ERP, cybersécurité OT) pour ton équipe maintenance / méthodes / IT-OT, BCUB3 propose deux formats :
- Cadrage 1 jour — 499 € HT : état des lieux archi OT, cartographie contraintes, livrable = note de cadrage avec options d’architecture + chiffrage indicatif.
- Mission 3 jours — 1 499 € HT : cadrage + prototype bout-en-bout OPC UA sur un périmètre pilote (1 automate, 3-5 variables, 1 client SCADA / MES). Livrable = code firmware + config automate + doc de reprise.
→ Discuter d’une mission d’intégration →
Pour aller plus loin
- XGBoost pour la maintenance prédictive industrielle — exploiter les données remontées via OPC UA pour prédire les défaillances.
- Architecture réseau industriel Purdue — où placer ESP32, switch, SCADA, automate dans une archi IT/OT propre.
- Agrégation de données industrielles — architecturer la couche de stockage + Grafana derrière la remontée OPC UA.