Interface PLC
Vue d'ensemble
Type de carte industrielle
|
Arduino M-duino
|
Raspberry pi ou tout autre carte avec des GPIO tournant sur Linux
|
Entrée ou sortie haut niveau, avec interface modbus
|
Entrée ou sortie haut niveau, avec interface REST
|
PLC Siemens S7
|
Autre PCL utilisant un protocole de dialogue spécifique
|
Système industriel SCADA
|
Protocole d'échange utilisé
|
Spécifique développé par Copliant
|
Spécifique développé par Copliant
|
Modbus TCP
|
REST
|
Profinet
|
|
|
Jeu d'instructions Storga à utiliser pour : Accéder directement aux broches de la carte
|
plc_pin
|
plc_pin
|
plc_pin
|
receive_file exchange_file
|
plc_pin
|
plc_call
|
|
Jeu d'instructions Storga à utiliser pour : Dialoguer avec la boucle de décision d'un PLC (automate)
|
plc_buffer_read plc_buffer_write
|
plc_buffer_read plc_buffer_write
|
|
|
plc_buffer_read plc_buffer_write
|
plc_call
|
variable
Parfois plc_buffer_read et plc_buffer_write Parfois REST
|
Jeu d'instructions Storga à utiliser pour : Appeler une fonction développée spécifiquement
|
plc_call
|
plc_call
|
|
|
|
|
|
Le cas des cartes Arduino ou M-duino
Pour les cartes Arduino ou M-duino, l'interface Storga est assurée par une librairie 'StorgaBridge' fournie par Copliant.
Cette librairie peut être utilisée de deux manières :
•
|
Soit en se contenant d'ajuster le fichier contenant les paramètres de la carte (nom, mot de passe, adresse IP, adresse de la passerelle réseau, etc) puis en accédant aux broches de la carte directement depuis un programme Storga, via l'interface bas niveau décrite ci-dessous
|
•
|
Soit en développant votre propre boucle de contrôle temps réel (écrite en C ou C++) qui va tourner sur l'Arduno ou la M-Duino, et en y connectant Storga via des buffers partagés, via l'interface haut niveau décrite ci-dessous
|
Dans les deux cas, vous pouvez aussi écrire dans l'environnement Arduino des fonctions complexes pour pour accéder et piloter des capteurs, écran ou autres appareils plus sophistiqués, en vous basant éventuellement sur d'autres librairies Arduino. Vous pourrez accéder à ces fonctions depuis Storga, via la fonction 'plc_call' décrite à la fin de ce document.
Les propriétés de la librairie 'StorgaBridge' qui assure l'interconnexion de la carte avec Storga, et qui fonctionne au dessus de la couche réseau UDP, sont :
•
|
Le protocole est crypté. La cryptographie mise en place s'oppose à ce qu'un logiciel espion ayant accès au réseau puisse : lire les capteurs de la carte Arduino ou M-duino, en positionner les sorties, déterminer les valeurs lues par Storga, les modifier au vol pour tromper Storga.
|
•
|
La liaison entre la carte et le serveur Storga peut se faire au travers d'une connexion Internet sans adresse IP fixe. Storga déterminera automatiquement l'adresse IP de la box Internet à laquelle la carte est reliée.
|
•
|
Le protocole peut traverser de manière transparente une passerelle NAT, sans qu'il soit nécessaire de mettre en place un port forwarding UDP.
|
Le cas des cartes Raspberry pi ou autres cartes tournant sur Linux
Pour les cartes tournant sous Linux, par exemple les Raspberry pi, l'interface Storga est assurée par un démon (exécutable 'storga_bridge') fourni par Copliant.
Cette interface utilise le même protocole, et donc dispose des mêmes caractéristiques et propriétés que l'interface Arduino ou M-duino que nous venons d'évoquer.
Déclaration et connection
La carte à interfacer doit être déclarée au niveau de la section 'Sites de fichiers (HTTP, FTP) et PLCs' de la page de définition du site Storga.
La clé 'Code du site' associé à chaque carte correspond au nom attribué à la carte, qui sera utilisé dans l'instruction 'plc_connect'.
Les champs supplémentaires à remplir sont :
•
|
Options supplémentaires
|
•
|
Droit nécessaire pour signer les programmes
|
Quand on utilise le protocole spécifique développé par Copliant pour interfacer les cartes de type Arduino, M-duino, ou Raspberry pi, le champ 'Utilisateur' n'est pas utilisé.
Voici le détail des options à utiliser au niveau du champ 'Options supplémentaire'
Type d'option
|
Type de carte concernée
|
Signification
|
arduino
|
Arduino, M-duino
|
Champ obligatoire qui active le protocole de dialogue spécifique développé par Copliant pour interfacer les cartes Arduino. Le sketch de la carte Arduino doit utiliser la librairie 'StorgaBridge'
|
storga_bridge
|
Rasberry pi, autre carte tournant sous Linux
|
Champ obligatoire qui active le protocole de dialogue spécifique développé par Copliant pour interfacer les cartes tournant sous Linux. Le service 'storga_bridge' doit tourner sur la carte.
|
modbus
|
Carte compatible Modbus TCP
|
Champ obligatoire qui active le protocole Modbus.
|
profinet
|
PLC Siemens S7, autre PLC compatible Profinet
|
Champ obligatoire qui active le protocole Profinet via la librairie Snap7.
|
tcp
|
PCL utilisant un protocol de dialogue spécifique basé sur TCP
|
Champ obligatoire qui active le protocole TCP bas niveau. Attention: cette solution n'est utilisable que si le protocole spécifique est 'suffisamment simple'.
|
udp
|
PCL utilisant un protocol de dialogue spécifique basé sur UDP
|
Champ obligatoire qui active le protocole UDP bas niveau. Attention: cette solution n'est utilisable que si le protocole spécifique est 'suffisamment simple'.
|
ssl
|
PCL utilisant un protocol de dialogue spécifique basé sur TLS
|
Champ obligatoire qui active le protocole TLS bas niveau. Attention: cette solution n'est utilisable que si le protocole spécifique est 'suffisamment simple'.
|
ip "ip1.ip2.ip3.ip4"
|
Presque toutes
|
Spécifie l'adresse IP de la carte.
|
bridge "nom_de_la_passerelle"
|
Modbus TCP
|
Ce paramètre est optionnel, et remplace le paramètre 'ip' lorsque la carte Modbus n'est pas accessible directement depuis le serveur Storga (derrière un NAT, ou sur un autre réseau Ethernet. On utilise alors une machine passerelle, faisant tourner le service 'TCP ports forwarding' de Pliant. Le nom de la règle de forwarding au niveau de la passerelle doit correspondre au nom du PLC dans Storga, et cette règle doit comprendre les trois paramètres 'source_host', 'target_ip', et 'target_port'. 'source_host' est le nom des différents serveurs Storga, séparés par des espaces.
|
name "nom"
|
PCL utilisant un protocol de dialogue spécifique basé sur TLS
|
Indique le nom de la carte.
|
port numéro
|
Arduino, M-duino, autre carte tournant sous Linux, PCL utilisant un protocol de dialogue spécifique
|
Spécifie le port TCP ou UDP utilisé par la carte.
|
port numéro
|
Modbus TCP
|
Spécifie le numéro d'unité de la carte (Unit identifier) à utiliser au niveau des packets Modbus TCP.
|
nat
|
Arduino, M-duino, autre carte tournant sous Linux
|
Spécifie que la carte se trouve derrière une passerelle NAT, et que l'adresse IP publique de celui-ci peut changer.
|
timeout seconds
|
Arduino, M-duino, autre carte tournant sous Linux, carte compatible Modbus TCP
|
Temps maximum autorisé pour recevoir la réponse de la carte.
|
retry n
|
Arduino, M-duino, autre carte tournant sous Linux
|
Nombre de retentatives en l'absence de réponse dans le temps apparti. La valeur par défaut est 3.
|
analog_bits n
|
Arduino, M-duino, cartes Modbus, carte Profinet
|
Résolution des entrées et sorties analogiques en nombre de bits. Ne positionner cette option que si la valeur déterminée automatiquement par Storga s'avère incorrecte.
|
L'instruction de connexion à la carte, à utiliser dans le script Storga, est :
plc_connect "nom_de_la_carte"
Le nom de la carte doit correspondre à ce qui a été indiqué au niveau de la colonne 'Code du site' au niveau de la table de définition des PLCs dans la page de définition du site Storga.
Un programme qui utilise l'instruction 'plc_connect' doit être signé, et le signataire doit disposer des droits correspondants à ce qui a été indiqué au niveau du champ 'Droit nécessaire pour signer les programmes'.
Par défaut, en cas d'erreur d'accès à la carte, le programme Storga va se mettre aussi en erreur.
Si l'on souhaite traiter les erreurs d'accès à la carte sans déclencher d'erreur au niveau du programme Storga, on ajoute l'option 'safe' au moment de la connection à la carte :
plc_connect "nom_de_la_carte" safe
Dans ce cas, le programme Storga peut à tout moment déterminer si la connexion à la carte a fonctionné correctement via la fonction 'plc_error' qui retourne une chaîne de caractères non vide en cas d'erreur :
if plc_error<>""
...
Toujours si l'on a utilisé l'option 'safe' au niveau de l'instruction 'plc_connect', les entrées dont la lecture aura échoué auront, au niveau du programme Storga, la valeur 'undefined'. Voir instruction 'plc_pin' ci-dessous.
Interface bas niveau : gérer directement les broches de la carte depuis Storga
Cette interface permet de gérer les broches de la carte. Cela signifie lire les entrées digitales et analogiques, et positionner les sorties digitales et analogiques.
On commence par déclarer chaque broche, via l'instruction 'plc_pin' dont la syntaxe est :
plc_pin nom pin numéro spécifications
Le nom est le nom de variable qui sera utilisé pour accéder à cette broche.
Les mots clés utilisables au niveau des spécifications sont :
input
|
Il s'agit d'une entrée
|
output
|
Il s'agit d'une sortie
|
digital
|
L'entrée ou la sortie est digital (0 ou 1, ou undefined en cas d'accès d'échec de lecture de la valeur de la broche)
|
boolean
|
Il s'agit aussi d'une entrée ou d'une sortie digitale, mais sa valeur sera true ou false au lieu de respectivement 1 ou 0
|
analog
|
L'entrée ou la sortie est analogique
|
reversed
|
L'entrée est inversée, c'est à dire que 0 dans Storga correspondra à 1 sur la carte, et 1 dans Storga à 0 sur la carte
|
Voici un exemple, qui attribue le nom 'led' à la broche 13 d'une carte Arduino, qui correspond effectivement à une LED présente sur la carte :
plc_pin led pin 13 analog output
Une fois la broche déclarée, on y accède comme une simple variable.
Pour les broches d'entrée, on utilise sa valeur.
Pour les broche de sortie, on la positionne en utilisant l'instruction ':='
Un exemple pourrait être :
led := 0.5
Comprendre la modèle sémantique utilisé par Storga
Quand le programme Storga démarre, les entrées sont toutes lues en une seule fois. Il est donc inutile de mettre en place une boucle dans le programme Storga qui attendrait par exemple qu'une broche bascule : elle ne basculera pas, parce que les entrées sont lues une seule fois au moment du démarrage du programme Storga.
De manière symétrique, toutes les sorties sont positionnées en une seule fois, à la fin de l'exécution du programme Storga. Il est donc impossible de positionner une sortie, faire boucler le programme Storga quelques instants, puis positionner à nouveau la même sortie.
Interface haut niveau : dialoguer avec la boucle de décision qui tourne sur la carte
Quand la carte gère un automatisme non trivial, celui-ci est généralement implémenté via des automates. En informatique, un automate est une manière standardisée d'écrire le programme. Elle comprend une variable d'état, qui indique la position actuelle dans l'automate, et une boucle de contrôle, qui tourne en permanence, et à chaque tour : lit un certain nombre d'entrées, en déduit les sorties à positionner, et un changement éventuel de l'état, c'est à dire de la position dans le diagramme de l'automate.
Le dialogue avec un automate se fait au moyen de deux instructions. La première permet d'envoyer une commande à l'automate, c'est à dire lui demander de changer d'état. La seconde permet de lire l'état de de l'automate.
Envoyer une commande se fait classiquement en écrivant dans un buffer logique. Pour cela, dans le programme Storga, on utilise l'instruction :
plc_buffer_write numéro_du_buffer offset position_initiale contenu_a_écrire
La partie 'offset position_initiale' sont optionnels, et ne servent que si l'on souhaite écrire en ne commençant pas à la position zéro du buffer.
Le contenu à écrire se spécifie sous la forme de paires d'arguments :
u1 valeur
|
écrire une valeur non signée sur un octet.
|
u2 valeur
|
écrire une valeur non signée sur deux octet.
|
u4 valeur
|
écrire une valeur non signée sur deux octet.
|
s1 valeur s2 valeur s4 valeur
|
la valeur est signée.
|
u2h valeur u4h valeur
|
la valeur non signée est 'high endian', c'est à dire l'octet de poid fort en premier.
|
u2h valeur u4l valeur
|
la valeur non signée est 'low endian'. u2 et u4 sont respectivement équivalent à u2l et u4l
|
s2h valeur s4h valeur
|
la valeur signée est 'high endian', c'est à dire l'octet de poid fort en premier.
|
u2l valeur s4l valeur
|
la valeur signée est 'low endian'.
|
tn chaîne
|
écrire une chaîne de caractères de longeur n. Si la chaine fournie est trop courte, elle sera complétée par des octets à zéro. Si la chaine fournie est trop longue, elle sera tronquée.
|
tnu chaîne
|
la chaîne de caractères est uncodée en UTF8. Dans ce cas, la longeur indiquée correspond au nombre de bytes, qui ne correspond plus forcément au nombre de caractères.
|
L'exemple suivant écrit 1+1+1+4+4+4+4+4 = 23 octets, en commençant à l'offset 2 du buffer 0 :
plc_buffer_write 0 offset 2 u1 1 u1 13 u1 1 u4 5000 u4 2^2 u4 0 u4 2^2 u4 0
Lire l'état de l'automate se fait classiquement en lisant le contenu d'un buffer logique. Pour cela, dans le programme Storga, on utilise l'instruction :
plc_buffer_read numéro_du_buffer offset position_initiale contenu_a_lire
Les arguments ont la même signification que pour 'plc_buffer_write'. Par contre, au lieu de fournir des valeurs à écrire, on indique des variables ou stocker le contenu lu, qui sont soit de type 'Int' quand le contenu à lire est numérique, soit de type 'Str' quand le contenu à lire est une chaîne de caractères.
L'exemple suivant lit dans la variable 'v' le contenu du premier octet du buffer 0 :
plc_buffer_read 0 u1 (var Int v)
Interfacer des capteurs complexes connectés à une carte Arduino, Raspberry pi ou autre
Il s'agit d'un mixte entre l'interface bas niveau et haut niveau.
L'instruction Storga est :
plc_call numéro_de_fonction write contenu_a_écrire read contenu_a_lire
Contenu à écrire et contenu à lire utilisent les mêmes paires d'arguments que les fonctions 'plc_buffer_read' et 'plc_buffer_write'. Par contre, l'instruction 'plc_call' ne dispose pas d'une option 'offset'.
Cette instruction 'plc_call' ressemble à une instruction 'plc_buffer_write' suivie d'une instruction 'plc_buffer_read'.
Dans le cas de cartes utilisant un protocole de dialogue spécifiques TCP, UDP ou TLS, elle y correspond exactement, et c'est la seule fonction qui sera utilisée dans la pratique.
En revanche, dans le cas d'une carte Arduio ou tournant sous Linux (par exemple Rasberry pi), elle correspond à tout autre chose qui est l'appel effectif d'une fonction spécifique.
Cette fonction spécifique sera implémentée en C ou C++, et connectée à l'interface carte ↔ Storga via l'instruction 'declare_function'.
On utilisera une telle fonction pour accéder depuis Storga à des capteurs complexes connectés à la carte via le bus i2c, piloter un écran LCD, etc.
Au niveau de l'environnement Arduino, la fonction à laquelle on accède a pour prototype :
int ma_fonction(const uint8_t *param,int psize,uint8_t *result,int rsize) {
...
}
La fonction retourne 0 en cas de success, une valeur non nulle en cas d'échec.
L'interface de cette fonction avec Storga se déclare via une variable globale de type 'FunctionBuffer' :
struct FunctionBuffer buffer_de_ma_fonction;
puis une instruction 'StorgaBridge.delcare_function' au niveau de la fonction 'setup' :
StorgaBridge.declare_function(&buffer_de_ma_fonction,numéro_de_la_fonction,ma_fonction);