Or ce graphe sera directement transcrit en
programme, sans aucune étude intermédiaire !
Les connaisseurs apprécieront l'astuce qui
consiste à assurer une maîtrise totale de la synchronisation
par la variable "étape". Ce souci de synchronisation
est constant dans tout le système de programmation, ce qui
affranchit l'utilisateur des aléas de la programmation événementielle
non synchronisée.
Ainsi, entre autres, toutes les entrées sont
lues et toutes les sorties sont positionnées en même temps, évitant
complètement les aberrations de comportement du système !
Voici donc le programme correspondant :
SUB
Graphe1 ()
STATIC etape AS INTEGER
SELECT CASE etape:
CASE 0:
io(MOTEUR_3)
= 0
etape = 1
CASE
1:
IF
En(5) < > 1 THEN EXIT SUB
io(MOTEUR_3) = 1
etape = 2
CASE
2:
IF
En(5) < > 0 THEN EXIT SUB
io(MOTEUR_3)
= 0
etape = 1
END
SELECT
END SUB
Qui dit mieux ?
Pour la lisibilité et la maintenance, nous
allons lui rajouter des commentaires:
SUB
Graphe1 ()
STATIC etape AS INTEGER ' = variable permanente
'===========================================================
' Principe du Multi-Tâche du système GRAPH-7:
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' - chaque graphe est un programme autonome
' - les tests sont toujours simples et rapides
' - ne jamais inclure de calculs dans une condition.
'===========================================================
SELECT CASE
etape:
CASE
0:'------------- initialisation: --------------
io(MOTEUR_3)
= 0
etape = 1
CASE
1:'------------- attente condition: -----------
IF
En(5) < > 1 THEN EXIT SUB ' tester l'entrée
'--------------
actions de l'étape 1: ---------
io(MOTEUR_3)
= 1 ' sortie de commande du moteur
etape = 2 ' étape suivante
CASE
2:'-------------- attente condition: ------------
IF
En(5) < > 0 THEN EXIT SUB ' arrêt du moteur ?
'--------------- actions de l'étape 2: ---------
io(MOTEUR_3)
= 0 ' RAZ relais moteur
etape = 1 ' étape suivante
END
SELECT
END SUB
Et pourtant, il y a
encore plus spectaculaire :
Programme d'un trieur:
Un cas de difficulté bien connu dans les
scieries est celui du trieur, qui consiste à devoir ranger dans
des "boxes", les billons (troncs découpés), en
fonction de leur longueur, de leur qualité ("choix")
etc.
Avec une programmation classique, une telle
mise en route s'éternise le plus souvent, au plus grand désespoir
du programmeur, de son employeur, et du Client !
Ici la difficulté de gérer des piles de
valeurs et des registres à décalage a été solutionnée par un
simple tableau dans lequel on range la valeur du codeur à
atteindre pour commander les éjecteurs, puis pour les désactiver
!
Cette simplicité est tellement spectaculaire
qu'elle peut sembler incroyable. Or ici c'est bien un exemple réel
qui est proposé (chaque fonction est un programme totalement
autonome, qui s'exécute de façon isolée) :
SUB
Nouveau_Billon (Numero_Box, longueur)
'================================================================
' Ceci est la Procédure qui est appelée lors de
la lecture
' de la cellule d'entrée du trieur
'
' - elle reçoit le numéro de box de destination
et la
'
longueur du billon
'
' - elle mémorise à quelle position future du
codeur il y aura
' l'action d'éjecter, et ensuite celle de RAZ du
vérin.
'
' NOTA: c'est le Graphe_Commande_Ejecteurs qui
'
exécutera ces actions
'================================================================
' On utilise les indices 0 et 1 du tableau, car
le début du
' tableau ne sera jamais utilisé par la suite.
' C'est pourquoi il faut sur-dimensionner le
tableau de
' au moins 2 emplacements.
' Ainsi, ce tableau remplace à la fois une pile
et un
'
registre à décalage.
'
1. calculer le centrage de l'éjecteur, selon la
longueur:
' 3. ranger ces valeurs dans l'ordre croissant du
codeur:
'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CALL Misajour_Trieur(Tableau_Boxes())
END SUB
SUB
Graphe_Commande_Ejecteurs ()
STATIC etape AS INTEGER, Fin_du_Tableau
'==========================================================
' - actionne le vérin de l'éjecteur lorsque le
codeur est à
'
la bonne valeur
' - mise à zéro (RAZ) du vérin apràs éjection
' - enlève la tâche exécutée de la pile
'==========================================================
SELECT CASE etape:
CASE 0:'---------------- initialisation:
---------------
Fin_du_Tableau
= UBOUND(Tableau_Boxes)
etape = 1
CASE
1:'---------------- test condition: ---------------
'
tester si une action reste à exécuter:
IF Tableau_Boxes(Fin_du_Tableau, 0) = 0 THEN EXIT SUB
' tester position du
codeur :
IF Counter(1) < Tableau_Boxes(Fin_du_Tableau,
0) THEN
'
puis mise à jour tableau pour la consigne suivante:
CALL Misajour_Trieur(Tableau_Boxes())
etape = 1
END
SELECT
END SUB
SUB
Centrer_Billon (Numero_Box, longueur, action&,
repos&)
' lire la position actuelle du codeur du trieur:
actuel&
= Counter(1)
'
puis:
'
lire offset (position Numero_Box) - (cellule de zéro)
' calculer position suivante action
' calculer position suivante repos (selon
installation)
END SUB
Mise en route du programme sans déplacement
sur le site !
Combien de semaines passe votre technicien chez le client pour
faire la même chose ?
C'est incroyable, mais bien réel !
Non destiné au public.Toutes
les marques citées sont des marques déposées. Les
images sont propriétaires de leurs ayants-droits
respectifs. Le Système Graph-7 et ses composants sont déposés
et/ou brevetés.