Erreur de logique
Je suis d'accord avec toi, je me suis trompé, c'est du OU qu'il faut, pas du ET.
Démarrage des rouleaux
Concrètement, puisqu'on détecte l'arrivée de la charge alors qu'elle est encore à l'extérieur de la navette, les rouleaux auront le temps d'accélérer avant que la charge arrive dessus.
Sauf si le transfert est interrompu... ou il y aura forcément des cas où tu auras raison.
Donc, au chargement, il faut démarrer les rouleaux dès que la piste est en position et donner le avalOk lorsque la vitesse de consigne est atteinte.
Au déchargement, le problème est l'inverse mais nous sommes liés à l'avalOK de l'élément suivant donc, on ne peut rien y faire.
Etat vide ou pleine d'une piste
Actuellement, il n'y a pas de cellule de présence de charge sur les pistes. C'est vrai, ça pose problème.
Je considère que, au moindre doute, on les considère pleine. Un message d'alarme peut être activé lorsqu'une piste est considérée pleine et qu'il n'y a aucune mission en cours sur cette piste... à ce moment là, l'utilisateur devra utiliser une commande "déclarer piste X vide" ou bien "livrer sur emplacement" (avec sélection de l'emplacement de livraison) sur l'IHM pour permettre la remise en route de la navette.
Découpage
Oui, mon découpage n'était pas exhaustif, j'aurais dû te le préciser.
Je suis tout à fait OK pour ton FB420 et les règle que tu proposes. Est-ce que tu programmes ça sous forme de système de vote ? ça serait bien, c'est plus simple à maintenir et à comprendre...
Protocole de fiabilisation
Ah oui ? Profinet IO découpe en sous-modules ? Bon alors, faisons simple...
L'option stabilité sur plusieurs cycles est la méthode à retenir, je pense... La CRC me paraît extrêmement efficace mais un peu surdimensionnée, non ? Et, dans tous les cas, l'identifiant est la référence. Mais en même temps, je me dis qu'avec ces automates, un calcul de CRC ne consomme pas énormément de temps de CPU et fait très professionnel. Surtout que, dans 15 ans, quand un petit jeune verra mon programme en se demandant pourquoi la réception de la nouvelle mission est temporisée ? ça ne sert à rien !... tu vois le truc ? Banco pour la CRC et le contrôle de l'ID.
Et OK pour la copie de travail rémanente. Cette copie sera recopiée dans la table de sortie de l'automate navette.
Ok pour le dimensionnement des tables d'échange.
FIFO : ah bon ? on peut faire autrement qu'en décalant la pile vers le bas ? :-D
compteur d'identifiant
Je trouve ton idée de recopier l'unixtime comme ID formidable ! Plus d'incrément mais, en plus, un horodatage d'enregistrement de la mission dans l'automate convoyage, c'est parfait !
Pack ML
Il faut distinguer l'état de la mission et l'état de la navette. Le pack ML ne concerne que l'état de la navette, pas l'état des missions.
Ce qu'il te reste à savoir
Détecteurs de présence : non, une palette centrée n'est pas détectée par aucun capteur. à la reprise, au moindre doute sur l'état des pistes, considérer qu'elles sont pleines.
je suis d'accord avec l'ordre d'ordonnancement que tu proposes. Si tu me fais un système de vote, je peux facilement modifier les priorités en cours de mise en service.
Temporisation de fin de déchargement : oui, tempo maintenue 500ms ou un truc comme ça. Cette tempo doit être réglable en paramètres.
système de vote
il s'agit d'une fonction du genre :
FCxxx : uint
begin
if condition1 then
FCxxx = 1;
return;
elsif condition2 then
FCxxx = 1;
return;
else
FCxxx = 1;
end
PROGRAMMATION DES SEQUENCES
Ouais, tu vas me faire des séquences en SCL avec des SELECT CASE.
ça me va, sur le principe.
Par contre, j'aime bien que les sorties du bloc soient pilotées directement par le grafcet, pas par un calcul en fonction de la valeur de l'étape.
C'est-à-dire que je créé une variable temporaire pour chaque sortie du bloc fonction. Ces variables temporaires sont initialisées à 0 en premier dans le bloc fonction. Par exemple :"_Sortie3 := false;"
C'est uniquement dans la ou les étape(s) du programme concernée(s) juste en dessous du case que je vais écrire la valeur dont j'ai besoin : "CASE n: _Sortie3 := TRUE;", vient ensuite la transition.
Et à la fin de mon bloc, je recopie la variable temporaire en sortie : "Sortie3 := _Sortie3;"
Est-ce que tu me suis ?
Téléchargement des fichiers que tu as créé
Dans ta prochaine réponse à ce post, peux-tu joindre TOUTES les dernières versions des sources SCL que tu as rédigé dans cette conversation ? Car, suite à ça, je vais prendre toutes les sources et les compiler dans TIA Portal et compléter le programme avec tous les appels.
Par contre, je risque de te demander des modifications, des ajouts et pour cela, j'aimerai que nous partions sur la même base, toi et moi. Tu me suis ?
- --------------------------- *
- --------------------------- *
- --------------------------- *
Rapport de compilation
J'ai du modifier Axe x types.scl de la manière suivante pour que ça compile :
TYPE "typeAxisStation"
VERSION : 0.3
STRUCT
line : Int; // Numero de la ligne de convoyage desservie
element : UInt; // Numero d'element fixe dans la table globale
defaultDirection : UInt; // Cote de desserte : 1 = CW, 2 = CCW
valid : Bool; // Station exploitable
position : Array[1..2] of LReal; // Cote d'accostage par piste [mm]
posName : String[16]; // Libelle affiche sur l'IHM
barcode : String[16]; // Reference emplacement dans l'ERP
END_STRUCT;
END_TYPE
Pour une raison que j'ignore, le nom de la variable "name" posait problème, je l'ai renommé "posName".
COM_Types.scl et G120C_Types.scl se sont compilés dans problème.
COM_Shared.scl
J'ai dû renommer la variable "counter" en "cnt" et c'est passé.
400 - Axe X
J'ai du remplacer #axis.Error par #axis.ErrorWord <> 16#0000;
idem dans "401 - Axe x modes"
Mais tout a compilé, je commence l'intégration.
- --------------------------------- *
- --------------------------------- *
- --------------------------------- *
Ok, tous les blocs compilent correctement, j'attaque l'intégration.
Premières opérations effectuées :
- j'ai déplacé les données décrites dans 011 - PARAM dans mon DB existant "Settings"
- j'ai déplacé les données décrites dans 012 - CONTEXT dans mon DB existant hmiOut (dont les variables sont configurées comme rémanentes).
- j'ai renommé 014 - LINK en "temp" pour bien me souvenir qu'il faut que les valeurs ne soient pas rémanentes, que ce sont des valeurs temporaires.
J'ai implémenté tous les FB dans l'OB1 et généré tous les DB d'instances.
J'ai inséré les données de hmiin / hmiout, settings et temp partout où c'est implicite dans tes commentaires et en comparant les types de données.
Il me reste quelques blancs...
D'abord, j'ai créé le FC "214 - Cells" pour écrire les infos des cellules sur les pistes.
Ensuite, il me reste des broches à renseigner :
213 - COM_MISSION (sur les deux instances)
- acceptNew : je ne sais pas quoi mettre
- abortRequest : je mettrai le RAZ grafcet et une commande supplémentaire venant de l'IHM, commande spécifique pour chaque piste. Si l'utilisateur doit vider physiquement la piste, alors il n'a qu'à créer une mission de déchargement depuis l'automate convoyage
- reqState : je ne sais pas quoi mettre
- reqStep : je ne sais pas quoi mettre
- reqErrorCode : je ne sais pas quoi mettre
Je ne sais pas quoi faire des sorties qui ne sont pas des messages d'alarme :
- missionValid
- newMission
- missionWaiting
420 - MISSION
Concernant les broches d'entrées :
- axisEnabled : je ne sais pas quoi mettre
- autoMode : je ne sais pas quoi mettre
- cruiseVelocity : je ne sais pas quoi mettre
Concernant les broches de sorties :
- busy : je ne sais pas quoi mettre
- fault : ok => message de défaut
- activeTrack : affichage seulement ?
- activeOperation : affichage seulement ?
- step : affichage seulement ?
410 - positionnement
Concernant les broches d'entrées :
- axisEnabled : je ne sais pas quoi mettre
430 - PISTE (les deux instances)
Concernant les broches de sorties :
- rollersRun : je ne sais pas quoi mettre
- speedReached : je ne sais pas quoi mettre
400 - AXE X
Concernant les broches d'entrées :
- RUN => je vais relire la conversation pour trouver ce que j'avais dit à ce sujet
Concernant les broches de sorties :
- ready : je ne sais pas quoi mettre
- faultActive : message de défaut
- mode : je ne sais pas quoi mettre
- fastMotionOk : je ne sais pas quoi mettre.
Dans ce bloc, la variable de sortie #mode est très utilisée en lecture à l'intérieur du bloc. Hors, il s'agit d'une sortie, elle n'est peut-être pas initialisée quand il y en a besoin et TIA Portal me marque un avertissement à ce sujet.
Est-ce que #_mode peut-être une variable statique recopiée en fin du bloc dans la sortie #mode ? (je n'ai pas analysé ton code en profondeur...)
Et... je me trompe où il manque encore le grafcet de gestion des modes de fonctionnement Pack ML ? Est-ce que tu peux ajouter ce qu'il faut ?
- ------------------------------ *
- ------------------------------ *
- ------------------------------ *
Voilà le détail du tableau de sorties qui piloteront la colonne lumineuse Modlight60 RGB :
- slices[0], Byte, %QB140, Slice mode
- slices[1], Byte, %QB141, Slice mode
- slices[2], Byte, %QB142, Slice mode
- slices[3], Byte, %QB143, Slice mode
- slices[4], Byte, %QB144, Slice mode
- slices[5], Byte, %QB145, Slice mode
- slices[6], Byte, %QB146, Slice mode
- slices[7], Byte, %QB147, Slice mode
- slices[8], Byte, %QB148, Slice mode
- slices[9], Byte, %QB149, Slice mode
- slices[10], Byte, %QB150, Slice mode
- slices[11], Byte, %QB151, Slice mode
- slices[12], Byte, %QB152, Slice mode
- slices[13], Byte, %QB153, Slice mode
- slices[14], Byte, %QB154, Slice mode
- slices[15], Byte, %QB155, Slice mode
- slices[16], Byte, %QB156, Slice mode
- slices[17], Byte, %QB157, Slice mode
- slices[18], Byte, %QB158, Slice mode
- slices[19], Byte, %QB159, Slice mode
- slices[20], Byte, %QB160, Slice mode
- slices[21], Byte, %QB161, Slice mode
- slices[22], Byte, %QB162, Slice mode
- slices[23], Byte, %QB163, Slice mode
Les octets de 0 à 19 sont les octets de pilotage de chacune des slices et peuvent prendre la valeur suivante :
-
BIT0, 1 et 2 :
- 000 Off
- 001 Red
- 010 Green
- 011 Yellow
- 100 Blue
- 101 Customized Color 1
- 110 Customized Color 2
- 111 White
-
BIT3, 4 et 5 :
- 000 Off or use Index 2024
- 001 Continuous
- 010 Blinking
- 011 Flashing
- 100 Gradations blinking
-
101 ... 111 Error
- BIT6 et 7 :
- 00 Off or use Index 2025
- 01 Low
- 10 Middle
- 11 Fast
Nous n'utiliserons pas le clignotement car il se fait entre éteint et la couleur choisie, ce qui est moche.
Je préfère avoir un fond orange qui clignote vert, par exemple...
L'octet[21] est le pilotage du buzzer :
-
BIT0 : ON marche / OFF arrêt du buzzer
-
BIT1, 2 et 3 : Type de buzzer :
- 000 Use Index 2030 (Default Continuous)
- 001 Intermittent
- 010 High and Low tones
- 011 Sweep
- 100 Continuous (500ms On/500ms Off)
- 101 Intermittent (500ms On/500ms Off)
- 110 High and Low tones (500ms On/500ms Off)
- 111 Sweep (500ms On/500ms Off)
- BIT4, 5, 6 et 7 : buzzer loudness :
- 0000 Use Index 2001 (Default 100 %)
- 0001 10 %
- 0010 20 %
- 0011 30 %
- 0100 40 %
- 0101 50 %
- 0111 60 %
- 1000 70 %
- 1001 80 %
- 1010 90 %
- 1100 100 %
L'octet[22] est un octet de configuration :
- BIT0, 1, 2 et 3 : function mode
- 0000 Use Index 810
- 0001 Stack Mode
- 0010 Level Mode
- 0100 Slice Mode
- 1000 ... 1111 Error
Ce paramètre devra toujours être écrit à 0100 Slice mode.
-
BIT4 et 5 : sync mode : on s'en fout
- BIT6 et 7 : User preferred Select color mode : on s'en fout.
Mode de fonctionnement de cette signalisation
Concernant le mode de fonctionnement, je pense qu'il faut que la colonne affiche l'état des sécurités de la machine, le mode de fonctionnement et l'état de marche.
Tu sais déjà comment gérer le buzzer, nous en avons déjà parlé.