Archives par mot-clé : EtherCAT

Raspberry pi : CODESYS & Al.

Bonjour,

Introduction

J’ai préparé une super démo que je devais présenter à des collègues et partenaires mais nous voici confinés et mes présentations devront attendre… Quoique… Quid d’un article ?

Les derniers articles traitaient de Raspberry Pi, de netPI Core / RTE et netIOT Edge « Connect », plateformes matérielles pour le marché industriel développées par Hilscher et basées sur le Raspberry Pi, de Docker, Node-RED, InfluxDB, Grafana et j’avais donc prévu de tester les SoftPLC (automates logiciels) CODESYS ou STRATON.

J’ai ainsi concocté une mixture de tout ceci, avec CODESYS cette fois car ma manipulation inclut le variateur INFRANOR qui se pilote via EtherCAT et que j’ai déjà évoqué ici.

Il se trouve que l’application de contrôle pour le Raspberry Pi dispose de EtherCAT Maitre, entre autres.

On montrera donc :

  • un automate CODESYS pilotant via EtherCAT un variateur INFRANOR,
  • un flow Node-RED avec un tableau de bord qui permet d’interagir avec le variateur via le serveur OPC de CODESYS,
  • ce flow renseigne également une base de données temporelles InfluxDB,
  • et une instance Grafana vient lire les données et les affiche.

Il est tout à fait possible de faire la même chose avec un Rasberry Pi mais par convenance je ferai ma démonstration avec un netPI RTE puisque c’est celui que j’ai sous la main.
Une version netPI Core suffit amplement à ma démo mais bien sûr j’aurais pu utiliser une version netPI Core / RTE ou netIOT Edge « Connect », cette dernière proposant une intégration native de Node-RED avec utilisation du protocole sécurisé HTTPS.

Le plan

Voici donc le plan d’ensemble, the big picture, de la solution envisagée :

CODESYS

J’ai donc suivi pas à pas les instructions pour la création du conteneur CODESYS et installé l’environnement de développement sur mon poste et les paquets runtime et gateway comme demandé.

J’utilise pour ma part l’interface WIFI (wlan0) pour accéder depuis mon PC de développement à la cible CODESYS.

Il est nécessaire d’importer le fichier ESI du variateur dans l’IDE CODESYS et l’on peut alors créer une configuration avec l’EtherCAT Master sur le port LAN (eth0).

On peut configurer les données échangées cycliquement entre l’automate et le variateur :

Mon programme en Structured Text ressemble à de l’Ada, c’est normal. 😉

J’ai défini quelques variables mappées côté EtherCAT :

Et d’autres remontant à l’IHM via le serveur OPC :

Jusque là, ça va :

Docker

Comme je veux que mon conteneur InfluxDB reste isolé du monde extérieur, je crée un réseau « myNet1 » auquel je vais connecter les conteneurs InfluxDB donc, le conteneur Node-RED qui va alimenter la base et le conteneur Grafana qui va y piocher :

J’ai donc créé mes conteneurs en suivant les instructions pour Node-RED, InfluxDB et Grafana en connectant les conteneurs sur mon réseau privé « myNet1 » :

Node-RED

Dans Node-RED, auquel on accède via le port 1880, j’ai ajouté quelques nœuds à ma palette comme node-red-dashboard, node-red-contrib-opcua, node-red-contrib-influxdb :

Puis j’ai développé ce flow qui d’une part communique avec CODESYS en OPC UA et d’autre part avec les composants du tableau de bord.
Il injecte également dans la base InfluxDB les échantillons de la vitesse.

On obtient un magnifique tableau de bord pour piloter le variateur INFRANOR :

On y voit le mode d’opération (3 : boucle de vitesse), la vitesse actuelle sous forme de jauge ou de diagramme, un curseur permettant de modifier la consigne, le mot d’état et pour finir le mot de contrôle.

0, 6, 7, 15… ça tourne ! 128 pour acquitter les défauts.

Et le menu hamburger permet d’accéder directement à la visualisation Grafana qui nous attend sur le port 3000 :

Le flow est disponible ici.

Puisque nous voilà confinés pour un moment, n’est-ce pas l’occasion rêvée de se mettre à l’autoformation ? 😉

Bien sûr, si vous ne disposez pas d’un variateur, tout autre esclave fera l’affaire étant donné que CODESYS supporte plusieurs technologies de bus de terrain sur Ethernet, CAN et liaison série.

Vous pourriez utiliser aussi le netHAT sur le Raspberry Pi, ou le netPI RTE / netIOT Edge « Connect », qui embarque un netX 51 permettant de gérer tous les protocoles sur Ethernet Temps Réel, ce qui autorise plein d’expériences amusantes.

Have fun comme disent nos collègues anglophones.

Cordialement,
Stéphane

A4A : Pilotage d’un variateur en EtherCAT

Bonjour,

J’espérais à voix haute pouvoir réaliser des manipulations avec un variateur communiquant en CANopen ou EtherCAT et mon souhait a été exaucé par un ami travaillant chez INFRANOR à Lourdes qui a bien voulu mettre à ma disposition un banc de test composé d’un variateur et d’un ensemble moteur / codeur… Miracle !

Je l’en remercie très chaleureusement !

Le banc est équipé d’un variateur XtrapulsPac et l’on peut depuis le site télécharger bien sûr la documentation, le logiciel de configuration Gem Drive Studio, le fichier ESI EtherCAT, en bref tout le nécessaire pour la manipulation.

Je n’ai pas rencontré de problème particulier avec Gem Drive Studio et j’ai pu configurer, régler le variateur et me familiariser avec son fonctionnement via la liaison série.

Pour ma démonstration, le PC de test étant un peu ancien, j’ai utilisé une carte Hilscher cifX au format PCI.

On peut télécharger une archive du DVD contenant la documentation, les outils de configuration et les firmwares ici.

Cependant, je préfère me fournir dans la base de connaissance qui dispose des dernières versions…

Ainsi, il est possible de se procurer la dernière version de l’outil de configuration SYCON.net.

Il est aussi possible de récupérer le dernier firmware EtherCAT Master .

On a donc importé dans SYCON.net le fichier ESI du variateur, menu « Network > Import Device Descriptions… », ne pas oublier de sélectionner le type de fichier « EtherCAT DDF », inséré l’esclave EtherCAT sur le réseau de la cifX configurée en EtherCAT Maitre et sélectionné les PDO en entrée et sortie pour un fonctionnement en boucle de vitesse.

Côté EtherCAT Maitre, dans la mémoire process de la carte Hilscher cifX donc, on retrouve les données d’entrée et sortie correspondantes :

Gem Drive Studio comme SYCON.net fonctionnent sous Microsoft Windows(R).

Cependant notre application va s’exécuter sous Linux avec les modifications PREEMPT_RT permettant d’obtenir un comportement temps réel.
Nous récupérerons donc les fichiers de firmware et de configuration pour les disposer dans l’arborescence du pilote cifX pour Linux.

Je travaille principalement sur des systèmes Debian et sur cet OS il existe un noyau Linux déjà compilé avec les patches PREEMPT_RT qui n’est donc qu’à une portée de clics ou d’une ligne de commande.
Cherchez « linux-image-rt » dans votre outil habituel et tant que vous y êtes installez également les en-têtes correspondants qui seront nécessaires pour la compilation du pilote Hilscher cifX qui n’est fourni que sous forme de code source.

Une fois installé, il suffit de redémarrer la machine en sélectionnant ce noyau.

Compilez ensuite le pilote comme expliqué dans la documentation relative. Ce pilote est en deux parties, l’une en espace noyau, uio_netx, qu’il vous faudra recompiler à chaque mise à jour du noyau, l’autre en espace utilisateur, la libcifx, qui est l’API pour votre application.

Voyez également la documentation pour l’utilisation du module si vous voulez vous passer de l’incantation en « root » :

modprobe -v uio_netx

Si tout ce passe bien, l’incantation fournit un résultat tel que :

On a disposé firmware et configuration dans le dossier idoine, par exemple :

Vous avez bien sûr installé « Ada for Automation », les dépendances et les outils pour le développement et vous avez navigué vers le répertoire contenant la démonstration « 122 ap7-wui ».
Un simple « make » doit vous permettre de générer l’application dont il est question dans cet article.

Cette application nécessite des droits spécifiques pour tourner avec des priorités temps réel.
Aussi il faut faire partie du groupe dédié ou être « root » pour pouvoir l’exécuter.

Cela démarre sur les chapeaux de roues en laissant une trace de ce style dans la console :

root@hf-test-2:/home/slos/Ada/A4A/demo/122 app7-wui# ./bin/App7_WUI_cifX
error
Log_Level = LEVEL_ERROR
2018-12-17 14:43:29.94 => A4A.Kernel.Sig_Handler : Waiting Signal Interrupt... Use Ctrl+C to exit
2018-12-17 14:43:29.94 => A4A.Kernel.Main_Task : Main_Task's ID is the_main_task_00005579443C2E50
Started at 2018-12-17 14:43:29.94
2018-12-17 14:43:29.94 => A4A.Generic_Periodic_Task : started !
2018-12-17 14:43:29.94 => A4A.Kernel.Main_Task : Initialising cifX Driver...
2018-12-17 14:43:31.61 => A4A.Kernel.Main_Task : Opening cifX Driver...
2018-12-17 14:43:31.61 => A4A.Kernel.Main_Task : Starting cifX TCP Server...
2018-12-17 14:43:31.61 => A4A.Kernel.Main_Task :
***********************************************
          Driver Information
Version     : cifX Toolkit 1.2.0.0
Board Count :  1
***********************************************

2018-12-17 14:43:31.61 => A4A.Kernel.Main_Task : Waiting for the firmware to start...
2018-12-17 14:43:36.61 => A4A.Kernel.Main_Task : Opening cifX Channel...
2018-12-17 14:43:36.61 => A4A.Kernel.Main_Task :
***********************************************
          Channel Information
Board_Name    : cifX0
Board Alias   : ECM
Device Number :  1250100
Serial Number :  20952

Firmware : EtherCAT Master
Version  :  4. 4. 9(Build  0)
Date     :  2018- 10- 10
***********************************************

2018-12-17 14:43:36.61 => A4A.Kernel.Main_Task : Setting Flag Host Ready...
2018-12-17 14:43:36.61 => A4A.Kernel.Main_Task : Setting Flag Bus On...
2018-12-17 14:43:38.61 => A4A.Kernel.Main_Task : (16#800C0021#)COM-flag not set
2018-12-17 14:43:38.61 => A4A.Kernel.Main_Task : Initialising Channel Messaging...
2018-12-17 14:43:38.61 => A4A.Kernel.Main_Task : Getting DPM IO Info...
2018-12-17 14:43:39.11 => A4A.Kernel.Main_Task :
***********************************************
          DPM IO_Info

Number of IO Block Info    :  2

Input Area :
Type of sub block    :  2
Flags                :  17
Offset               :  0
Length               :  10

Output Area :
Type of sub block    :  2
Flags                :  18
Offset               :  0
Length               :  6
***********************************************

2018-12-17 14:43:39.11 => A4A.Kernel.Main_Task : Calling Cold_Start...
2018-12-17 14:43:39.11 => A4A.Kernel.Main_Task : (16#800C0021#)COM-flag not set
Gnoga            :1.2b
Application root :/home/slos/Ada/A4A/demo/122 app7-wui/
Executable at    :/home/slos/Ada/A4A/demo/122 app7-wui/bin/
HTML root        :/home/slos/Ada/A4A/demo/122 app7-wui/html/
Upload directory :/home/slos/Ada/A4A/demo/122 app7-wui/html/
Templates root   :/home/slos/Ada/A4A/demo/122 app7-wui/
/js  at          :/home/slos/Ada/A4A/demo/122 app7-wui/js/
/css at          :/home/slos/Ada/A4A/demo/122 app7-wui/css/
/img at          :/home/slos/Ada/A4A/demo/122 app7-wui/img/
Boot file        :000-boot.html
HTTP listen on   ::8091
Press Ctrl-C to close server.
2018-12-17 14:43:39.96 : HTTP Server Started

Si je pointe mon navigateur sur l’adresse locale et le port choisi (:8091 cf. la trace), je peux piloter le variateur depuis le mot de contrôle et observer un signal en dent de scie sur la consigne et la mesure…

… tandis que je mate une vidéo de lapin…

… ce qui charge ma vieille CPU comme une bête …

Dans cette vue de « htop » on voit bien les priorités des processes de l’application temps réel, notamment les deux avec la priorité -89 sont les tâches « main » et « periodic », une priorité normale en FIFO étant à -50, -89 est une priorité plutôt haute donc.

C’est ce qui permet à ces tâches de se comporter honnêtement :

Ainsi, la tâche « main », cadencée à 1 ms, subit une fois sur mille un dépassement de son heure d’activation.

La vue d’état de la cifX montre des informations classiques…


… que je peux vérifier également depuis SYCON.net sur un autre poste :

Car « Ada for Automation » implémente « netX Diagnostic and Remote Access » comme déjà évoqué.

J’espère bien trouver un peu de temps pour mener d’autres expérimentations comme implémenter quelques fonctions de Motion Control

Cordialement,
Stéphane

Raspberry Pi 3 / SenseHAT / netHAT / netPi

Bonjour,

Je cherchais pour mes expériences une solution qui soit ludique, et aussi accessible à tout un chacun, et mes tribulations m’ont conduit à sélectionner un combo Raspberry Pi 3 + SenseHAT.

Hilscher France a donc fait l’acquisition de ces éléments chez KUBII :

Starter Kit Officiel Pi3
https://www.kubii.fr/fr/kits-raspberry-pi/1637-kit-demarrage-raspberry-pi3-3272496004207.html

Raspberry Pi Sense Hat
https://www.kubii.fr/fr/cartes-extension-cameras-raspberry-pi/1081-raspberry-pi-sense-hat-640522710799.html

Pourquoi donc un tel investissement me direz vous ?

Sans doute parce que depuis quelques temps cette plateforme économique et performante permet d’imaginer tout un tas d’utilisations dans ce qu’il est convenu d’appeler l’IoT, l’IIoT, Industry 4.0, etc…

Aussi, à l’instar de certains confrères, la société Hilscher a développé certains produits autour de cette plateforme comme le netHAT, le netPi et le Edge Gateway « Connect » :
https://www.netiot.com/interface/nethat/
https://www.netiot.com/netpi/industrial-raspberry-pi-3/
https://www.netiot.com/edge/

Hilscher innove en testant le canal de vente Amazon et l’on peut y acheter le netHAT et le netPi :
https://www.amazon.fr/Hilscher-NXHAT52-RTE-nethat-52-de-RTE/dp/B01MFH0FP9
https://www.amazon.fr/Industrial-Raspberry-Industry-Communication-4×1-2Ghz-Real-Time-Ethernet/dp/B0756XD2CN

Pour ces produits, Hilscher France n’assure pas de support.
Cependant, l’on peut vous proposer une formation !

Le netHAT est fourni avec un pilote Linux compilé, des firmwares en version limitée à 32 octets d’E/S pour EtherCAT, Ethernet/IP et PROFINET IO Device et bien sûr de la documentation.

Le tout s’installe sans encombre sur la Raspbian et ça tombe en marche comme sur le plan.

Vous pouvez donc vous familiariser avec la technologie Hilscher pour une quarantaine d’euros, ce qui est modique vous en conviendrez aisément.

Bien sûr, « Ada for Automation » peut tout à fait être utilisé avec le netHAT. J’y reviendrai bien sûr.

Avec un Raspberry Pi + un netHAT, on peut aussi tester le concept netPi et développer des applications qui tourneront sur le netPi sans modification.

Bref, je souhaitais monter une manipulation avec un Rasberry Pi 3, un SenseHAT pour des capteurs pas chers et un netHAT pour connecter ce bijou de technologie à votre automate préféré.

En fait, le SenseHAT et le netHAT ne peuvent pas se monter l’un sur l’autre comme on pourrait le penser de prime abord.

Je pensais développer un binding Ada pour le SenseHAT mais ce n’est pas si simple.
Le langage choisi par l’équipe Raspberry est plutôt le Python et la plupart des bibliothèques fournies pour les « HAT » sont en Python.
La bibliothèque disponible pour le SenseHAT est donc en Python aussi et utilise d’une part une bibliothèque en C++ qui gère nombre de capteurs et d’autre part le framebuffer pour les LEDs et un IO device pour le joystick.

Monsieur Phil Munts, que je remercie, m’a bien fait part de sa librairie :
http://git.munts.com/libsimpleio/ada/

Mais je voulais quelque chose de super vite fait et j’ai penché pour une solution mettant en œuvre un framework Modbus développé par un collègue, Monsieur Luc JEAN, que je remercie chaleureusement :
https://github.com/ljean/modbus-tk

Pourquoi donc ? « Ada for Automation » disposant de la fonctionnalité Modbus TCP Client et le framework permettant de réaliser très simplement un serveur Modbus TCP, il suffisait donc de raccrocher les données des capteurs dans les registres du serveur.

J’ai utilisé également ce bout de code qui m’a bien aidé, je remercie aussi son auteur :
https://frank-deng.github.io/python-kbhit.en.html

Le SenseHAT dispose d’une application de simulation avec interface graphique et il est possible d’utiliser celle-ci en lieu et place du matériel tel que dans l’exemple suivant.

SenseHAT Simu GUI
SenseHAT Simu GUI

On y démarre depuis un terminal :

python 3 sense-omb.py
python 3 sense-omb.py

Et on teste par exemple avec Modbus Poll :

Modbus Poll Example
Modbus Poll Example

En Python, c’est une vingtaine de lignes de code pour remonter température, pression, hygrométrie et cap :

#!/usr/bin/env python
# -*- coding: utf_8 -*-
"""
 Modbus TestKit: Implementation of Modbus protocol in python

 (C)2009 - Luc Jean - luc.jean@gmail.com
 (C)2009 - Apidev - http://www.apidev.fr

 This is distributed under GNU LGPL license, see license.txt
"""


import sys
import struct

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp

from sense_emu import SenseHat

import kbhit, time;

sense = SenseHat()

def main():
    """main"""

    kbhit.init();
    running = True;

    logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")

    try:
        #Create the server
        server = modbus_tcp.TcpServer(port=1502)
        logger.info("running...")
        logger.info("enter 'q' for closing the server")

        server.start()

        slave_1 = server.add_slave(1)
        slave_1.add_block('0', cst.HOLDING_REGISTERS, 0, 100)

        while running:
            if kbhit.kbhit():
                ch = kbhit.getch();
                if 'q' == ch:
                    running = False;

            slave_1.set_values('0', 0, struct.unpack('>HH', struct.pack('>f', sense.temp)))
            slave_1.set_values('0', 2, struct.unpack('>HH', struct.pack('>f', sense.pressure)))
            slave_1.set_values('0', 4, struct.unpack('>HH', struct.pack('>f', sense.humidity)))
            slave_1.set_values('0', 6, struct.unpack('>HH', struct.pack('>f', sense.compass)))

            time.sleep(0.1);

    finally:
        server.stop()
        kbhit.restore();

if __name__ == "__main__":
    main()

C’est naturellement pas très temps réel mais c’est très bien pour mon cas d’école.

Et en plus, on peut facilement imaginer de reproduire ce schéma avec d’autres HATs comme le « Automation HAT » par exemple :
https://shop.pimoroni.com/products/automation-hat

Vous pouvez donc remonter les données du SenseHAT vers votre automate préféré disposant d’une connectivité Modbus TCP Client.
Bon, en travaillant un peu, ça doit fonctionner dans les deux sens, hein !

Quid du netHAT ? Si on utilise l’application de simulation SenseHAT on peut bien sûr le mettre sur le même Raspberry Pi et se connecter en local.
Si l’on souhaite de vraies données physiques, il faudra l’installer sur un autre Raspberry Pi, et le faire communiquer avec le premier, toujours en Modbus TCP.
C’est trivial avec « Ada for Automation » et je vous le montrerai ce tantôt.

Cordialement,
Stéphane

A4A : Exemple d’application 6 : Modbus TCP Client / Serveur + deux canaux Hilscher

Bonjour,

Comme je l’indiquais récemment l’application « app6_gui » offre :

  • un serveur Modbus TCP pour y connecter par exemple un SCADA du marché,
  • une fonction IO Scanning avec une tâche client Modbus TCP par serveur d’E/S,
  • deux canaux cifX Hilscher, pour gérer deux cartes, par exemple une PROFIBUS DP Maitre et une EtherCAT Maitre, ou pour gérer une carte à deux canaux comme par exemple un PROFIBUS DP Maitre et un CANopen Maitre,
  • une interface graphique avec GtkAda, permettant de consulter l’état des communications et de l’application et de démarrer ou arrêter les programmes utilisateur,
  • l’intégration du « cifX TCP Server » permettant la configuration et le diagnostic des cartes par SYCON.net via une connexion TCP/IP.

Je voulais faire un article à part pour cette application, avec des images. J’ai donc monté la manipulation suivante :

Manip-2016-01-08

On a donc un PC, sous Debian Jessie et un noyau Linux 64 bit standard, avec deux cartes Hilscher PCI, une cifX 50-DP configurée en Maître PROFIBUS DP et une cifX 50-RE configurée en Maître EtherCAT :

PC+2cifX50

Comme Esclave PROFIBUS DP j’ai une carte Hilscher CB-AB32-DPS, un « piano » avec deux octets en entrée et autant en sortie qui permet de monter une manipulation en deux secondes et demie :

CB-AB32-DPS

Pour EtherCAT, j’ai également un « piano », le NXIO 500-RE, qui reçoit sa fonctionnalité en insérant la carte MMC qui convient, ici EtherCAT Esclave, avec toujours deux octets d’E/S :

NXIO-500-RE

Le client Modbus TCP qui interroge le serveur de l’application 6 est Modbus Poll dont j’ai déjà fait mention il y a longtemps.

Quant au client Modbus TCP, ce que certains appellent IO Scanning, il est configuré pour exécuter deux requêtes sur un serveur d’un genre particulier sur lequel je reviendrai plus tard.

Je vous épargne la trace laissée par l’application dans le terminal depuis lequel elle est lancée, qui est certes informative, voire même didactique, mais un peu indigeste.

La fenêtre principale s’ouvre et l’on y trouve les onglets suivants.

La vue « Identité », (remarquez la version !) :

A4A-App6-Identity

La vue « Etat général » en deux bouts :

A4A-App6-GeneralStatus1

A4A-App6-GeneralStatus2

On notera la présence des informations d’état des deux tâches « Fieldbus ».

On trouve ensuite la vue d’état du serveur Modbus TCP qui affiche les compteurs de requêtes, et bien évidemment celui qui bouge est celui de la fonction 3 configurée côté Modbus Poll :

A4A-App6-ModbusTCPServer

La vue « Client Modbus TCP » affiche les informations d’état concernant les deux requêtes configurées pour le serveur secret pour le moment, le second client étant désactivé :

A4A-App6-ModbusTCPClients

Notez que lorsque l’on rajoute des requêtes au niveau de la configuration des clients, la vue d’état est bien sûr adaptée automatiquement.

Puis viennent les deux vues d’état des canaux Hilscher cifX.

L’un est donc PROFIBUS DP Maître :

A4A-App6-ProfibusDPMaster

Et l’autre est EtherCAT Maître :

A4A-App6-EtherCATMaster

Le programme utilisateur à l’œuvre dans les trois tâches est très sensiblement identique :

   procedure Process_IO is

      Elapsed_TON_1 : Ada.Real_Time.Time_Span;

   begin

      if First_Cycle then

         Output_Byte := Pattern_Byte;

         First_Cycle := False;

      end if;

      Tempo_TON_1.Cyclic (Start   => not TON_1_Q,
                          Preset  => Ada.Real_Time.Milliseconds (500),
                          Elapsed => Elapsed_TON_1,
                          Q       => TON_1_Q);

      if TON_1_Q then

         case Cmd_Byte is

         when 0 =>
            Output_Byte := ROR (Value => Output_Byte, Amount => 1);

         when 1 =>
            Output_Byte := ROL (Value => Output_Byte, Amount => 1);

         when others => Output_Byte := Pattern_Byte;

         end case;

      end if;

   end Process_IO;

On trouve aussi dans « Ada for Automation » une application exemple 5, « app5 », identique à « app6 » mais qui ne gère elle qu’un seul canal Hilscher cifX.

Mais quel est donc ce serveur Modbus TCP secret dont je vous entretiens depuis le début ?
La NXIO 500-RE ne pourrait-elle faire l’affaire avec une MMC ad hoc ? Sans doute, mais pour des raisons qui m’échappent ce firmware n’existe pas…

Aussi, je me suis dit que je n’avais qu’à utiliser le « kernel 0 », issu de « app1simu », et qui fournit un serveur Modbus TCP.
Oui mais, et les boutons et LEDs ? GtkAda aurait bien sûr pu convenir mais comme je jouais avec Gnoga…

Taa taan ! Voilà un « piano » piloté depuis le navigateur !

A4A-App6-A4A-Piano-Local

Comme c’est du SVG, donc du vectoriel, même depuis un mobile ça se pilote.

Et en plus l’application supporte les connexions multiples ! On peut jouer à plusieurs ! J’adore…
Promis, dès que mon code est un peu plus propre je l’envoie sur le dépôt.

Cordialement,
Stéphane

A4A : Applications et Noyaux

Bonjour,

Le framework « Ada for Automation » est fourni avec un certain nombre d’applications exemples, simple applications consoles ou avec interface graphique en GtkAda, et très bientôt je l’espère avec interface web grâce à Gnoga, un autre framework que je vous avais présenté très brièvement ici, et avec lequel je m’instruis beaucoup tout en m’amusant.

Ainsi par exemple le projet de base A4A est proposé en version console, dont le fichier projet est « a4a.gpr », et en version interface graphique avec « a4a_gui.gpr ».
Cette application est la plus simple possible et joue avec les deux octets d’entrée et sortie à sa disposition, ne mettant en œuvre que des fonctions de rotation et d’affectation.

Ce projet repose sur un noyau, partagé par les deux versions, qui gère le programme utilisateur, un serveur Modbus TCP et des clients Modbus TCP, un pour chaque serveur d’E/S.
La tâche principale collabore avec une tâche périodique annexe via la nouvelle DPM générique dont il a été question précédemment, chacune des tâches disposant d’un programme utilisateur à exécuter à l’état RUN.
Le serveur Modbus TCP comme les clients échangent leurs données avec la tâche principale également via des DPM spécifiques dont le rôle est d’assurer la cohérence des données échangées.

Via le mécanisme d’extension des projets supporté par la suite d’outils fournis par AdaCore, on peut construire des projets héritant des fichiers du projet parent et ajoutant de nouveaux fichiers ou en les substituant s’ils portent le même nom.

C’est ce mécanisme qui est utilisé par exemple avec l’application 1 présentée ici, et encore ici.

Aussi, comme cette application hérite de tout A4A, son dossier source ne contient que ce qui lui est propre, son identification, sa configuration et le programme utilisateur.

Pour cette application 1, ne disposant pas de la partie opérative on a développé une application de simulation, nommée « app1simu ».
Cette application ne nécessitant que la fonction serveur Modbus TCP on a créé un nouveau noyau issu du noyau de A4A auquel on a ôté la gestion des clients Modbus TCP.
Ce noyau logeait dans le dossier de l’application « app1simu » puisqu’il lui était spécifique.

Il en fut de même pour l’application 2 qui met en œuvre une carte Hilscher cifX en lieu et place des clients Modbus TCP.

Et encore de même avec l’application 3 qui remplace les clients Modbus TCP par un maitre Modbus RTU.

Le problème dans cette situation c’est que pour réutiliser un noyau de « app1simu », de « app2 » ou de « app3 », il eu fallut hériter de ces projets ou lister les sources que l’on souhaitait réutiliser, c’est possible, ou pire dupliquer les sources, beurk… Bref, ce n’était pas satisfaisant d’autant que je comptais multiplier les noyaux… On multiplie ce qu’on peut.

J’ai donc réorganisé le framework de sorte que les noyaux se retrouvent dans leurs propres dossiers.
Piloté par une variable externe ou un scénario depuis GPS, le dossier sélectionné est ajouté au projet en cours de traitement.

Ainsi le noyau de « app1simu » est maintenant le « kernel0 », celui de A4A est le « kernel1 », celui de « app3 » est devenu « kernel2″…

C’est beau et ça fonctionne à peu près.
La variable est définie dans un fichier de projet partagé par les autres fichiers de projets, le projet « shared.gpr », et reçoit une valeur initiale par défaut qui est « kernel1 » si elle n’est pas définie par ailleurs.
Attention cependant de laisser GPS terminer ses opérations de mise à jour des références croisées avant de changer de noyau au moyen de la liste déroulante du scénario sous peine de corruption de sa base de données, du moins avec la version Debian.
Ce n’est pas très grave puisqu’il suffit de supprimer celle-ci pour qu’elle soit reconstituée mais c’est un peu pénible.

...
   type Kernel_Type is
      ("kernel0",   --  Modbus TCP Server
       "kernel1",   --  Modbus TCP Server + Modbus TCP IO Scanning
       "kernel2",   --  Modbus TCP Server + Modbus RTU IO Scanning
       "kernel3",   --  Modbus TCP Server + one Hilscher cifX channel
       "kernel4",   --  Modbus TCP Server + Modbus TCP IO Scanning
                    --  + one Hilscher cifX channel
       "kernel5"    --  Modbus TCP Server + Modbus TCP IO Scanning
      );            --  + two Hilscher cifX channels

   Kernel : Kernel_Type := external ("Kernel", "kernel1");
...

Et l’on voit que le noyau de « app2 » est devenu le « kernel3 », que le « kernel4 » fusionne le « kernel1 » et le « kernel3 » et que le « kernel5 » ajoute un canal Hilscher au « kernel4 ».

J’ai bien sûr créé les applications exemples « app5 » qui roule avec le « kernel4 » et « app6 » motorisé par le « kernel5 », le tout en version console ou GUI.

Comme chaque canal Hilscher est susceptible de gérer un bus de terrain différent, classique ou sur Ethernet Temps réel, chaque canal est géré par une tâche indépendante qui exécute son propre programme utilisateur avec une période que l’on peut configurer.
Les tâches « fieldbus » communiquent avec la tâche principale via les DPM génériques déjà évoquées.

Ainsi l’application « app6_gui », mon top model ;-), offre :

  • un serveur Modbus TCP pour y connecter par exemple un SCADA du marché,
  • une fonction IO Scanning avec une tâche client Modbus TCP par serveur d’E/S,
  • deux canaux cifX Hilscher, pour gérer deux cartes, par exemple une PROFIBUS DP Maitre et une EtherCAT Maitre, ou pour gérer une carte à deux canaux comme par exemple un PROFIBUS DP Maitre et un CANopen Maitre,
  • une interface graphique avec GtkAda, permettant de consulter l’état des communications et de l’application et de démarrer ou arrêter les programmes utilisateur,
  • l’intégration du « cifX TCP Server » permettant la configuration et le diagnostic des cartes par SYCON.net via une connexion TCP/IP.

Je vous remercie pour votre attention et vous souhaite une très bonne et heureuse année 2016 pleine de projets, personnels comme professionnels, et de réussite.

N’hésitez pas à nous solliciter.

Cordialement,
Stéphane