MARKDOWN 45
Prompt navette By jledun on 1st September 2026 03:50:59 PM

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. Je te laisse me faire une proposition sans perdre de vue la simplicité et la lisibilité des informations affichées.

Puisque nous avons plusieurs Slices, je voudrais faire des transition progressive sous forme de chenillard.

Sur mon IHM, j'ai attributé la couleur verte au mode automatique, orange au mode manuel et bleu au mode maintenance.

Orange étant déjà utilisé pour la signalisation des sécurités, je vais redéfinir le bouton "mode manuel" en blanc, je pense... Y'a-t'il un standard pour cela ? Cela ne me pose aucun problème de modifier la couleur de mes boutons ;-)

J'ai déjà intégré la commande du buzzer, tu n'as pas à t'en occuper.

  • ------------------------------------- *
  • ------------------------------------- *
  • ------------------------------------- *

Je travaille sur l’automate convoyage.

Je voudrais mettre à jour ma fonction de gestion des lignes de convoyage en intégrant une fifo de produits.

Du sens de la ligne se déduit le sens de la fifo (de gauche à droite ou de droite à gauche).

J’ai déjà une base de programme avec des structures de données déjà établies pour les lignes de convoyage et les éléments, les UDT sont joints à ce prompt.

Chaque ligne de convoyage comprend une liste de 1 à 16 éléments, classés de gauche à droite dans le tableau, quelque soit le sens de fonctionnement de la ligne.

Comme je te disais, j'ai déjà une fonction qui gère la ligne et chacun des éléments.

Nous allons intégrer le mode de gestion avancée dans le FB1009_LIGNE_AVANCEE et le FB1010_ELEMENT_AVANCE.

Dans ce nouveau mode de fonctionnement avancé, l'élément servira a :

  • lire l'état des cellules C1 (à gauche) et C2 (à droite) avec fonction de filtrage anti rebond
  • pilote le ou les rouleaux motorisés qui sont associés à l'élément (CW et CCW)
  • informer la ligne que les rouleaux sont en marche (= CW ET rCW + tempo ou CCW et rCCW + tempo)
  • informer la ligne d'un défaut moteur ou time out (CW ou CCW dure trop longtemps)

Je me charge de développer ce bloc fonction FB1010_ELEMENT_AVANCE

Il y a déjà dans l'automate convoyage une base de données pouvant gérer lignes[0..38] lignes (la ligne 0 n'existe pas) et elements.e[0..200] éléments de convoyage. Cette base de données est dans le DB1000_MANUT.

Chaque élément peut piloter 1 ou 2 rouleaux motorisés, le bloc élément est instancié dans un FB global pouvant gérer 1 ou 2 rouleaux motorisés.

Chaque ligne de convoyage gèrera une liste de produits.

Sur chaque ligne, il y a elements[1..16] of int : liste des éléments qui composent la ligne, saisie obligatoirement de gauche à droite.

La valeur actuelle de elements[2] (par exemple) est l'indice de l'élément dans la base de données d'éléments.

Il y a 4 modes de fonctionnement :

  1. Arrêt -> la ligne est à l'arrêt, les éléments ne sont pas pilotés automatiquement

  2. Manuel -> l'utilisateur met en marche toute la ligne vers la gauche en maintenant appuyée la pédale bleu. L'utilisateur met en marche toute la ligne vers la droite en maintenant appuyée la pédale jaune. Le démarrage de chaque élément est cadencé pour limiter les courants d'appels.

  3. Manuel asservi -> je n'ai pas encore trouvé l'utilité d'un tel mode de fonctionnement, je ne sais pas le décrire. Peut-être un mode manuel où l'automate tient compte du positionnement des palettes sur les cellules mais piloté uniquement sur pédales ?

  4. FIFO -> dans le sens 2 (CW vers la droite), entrée de la ligne à gauche, sortie à droite ; dans le sens 1 (CCW vers la gauche), entrée de la ligne à droite, sortie à gauche. Dans le sens 2 (CW vers la droite), l'entrée d'une palette se fait sur la cellule C1 (à gauche) de l'élément placé à gauche. La sortie d'une palette se fait par action maintenue sur la pédale jaune. La sortie d'une palette est confirmée sur front descendant de la cellule C2 de l'élément à droite de la ligne. Idem dans le sens 1 mais en inversant droite et gauche.

  5. LIFO -> dans le sens 2 (CW vers la droite), entrée de la ligne à droite, sortie à droite ; dans le sens 1 (CCW vers la gauche), entrée de la ligne à gauche, sortie à gauche

Pour la suite de ce post, quand j'écris "produits", lire "liste des produits présents sur la ligne".

La position du produit dans la liste de produits indique l'ordre dans lequel il est rentré.

La valeur attribué au produit dans la liste des produits est l'indice de l'élément sur lequel il se trouve.

J'ai déjà pris quelques notes sur le fonctionnement que j'envisage et je te le décris dans l'ordre à réaliser :

  1. tri de la liste de produits
  2. analyse des états des éléments qui composent la ligne
  3. décision :
    • front montant sur la cellule d'entrée de la ligne = intégration d'un nouveau produit dans la liste de produits
    • front descendant sur la cellule de sortie de la ligne = destruction du produit correspondant (selon mode de fonctionnement FIFO ou LIFO)
    • front montant sur la cellule de sortie d'un élément = le produit s'est déplacé d'un élément vers la gauche ou la droite en fonction du sens = arrêt des moteurs si l'élément suivant est plein.
  4. application des décision : mise à jour des pilotages moteurs de tous les éléments de la liste des éléments de la ligne
  5. mise à jour des données

La discussion est ouverte, j'attends les sources SCL pour le FB1009_LIGNE_AVANCEE, j'avance sur l'élément avancé de mon côté pendant que tu réfléchis...

Paste is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.