Ich habe im beigefügten CoDeSys-Programm ein Programm "Werkstueck_Verwaltung" welches ich mit einem weiteren "Visu_Band" in einen und der eingefügt habe.
Mein Problem ist nun, wenn ich die Variable "Stueck-Annahme" auf True setzte/force wird bei Priorität 5 die IF-Anweisung nicht ausgeführt, bei Priorität 2 klappt dies teilweise.
-> Was habe ich falsch gemacht????
Auch in diesem Programm "WErkstueck_Verwalt" habe ich versucht, mit den zwei Case-Anwendungen Werte in die Visu zu schreiben und anschließend programminterne Variable wieder mit dem neuen, evtl. durch Eingabe, veränderten Wert, zu beschreiben. Kann man hier evtl. [i],.. arbeiten?
Das Ergebnis sollte sein, es gibt ca. 30 verschiedene Werkstücke mit jeweils ca. 12 Parametern (siehe 1. Zeile Case =vollständig), dass diese Variablen über die Visu geändert werden können.
Wird nun in der Visuvalisierung z.B. das Werkstück 15 aufgerufen, so sollen die 12 Parameter in die Visu PLC_VISU geladen werden (alle 12 Variabeln stammen aus z.B.Werkstueck_15 und werden auf die Variable ..._NrX geschrieben).
Wird nun der Wert über die nummerische Anzeige geändert oder boolsche_Elemente angeklickt, müssen anschließend die Änderungen oder einfach alle Parameter wieder in das Programm z.B. Werkstueck_15 geschrieben werden.
Ein Linienzug soll mit einem variablen Ende und einem fixen Ende in der Visu angezeigt werden. Wie ist dies möglich, denn das eine Ende darf sich nicht bewegen und das andere Ende bewegt sich lediglich in X-Richtung (Folge: Pfreillänge wird kleiner und gleichzeitg weißt diese dann immer wieder einen anderen Winkel auf +
Ein Viereck soll sich in x-richtung bewegen (realisiert) und gleichzeitg soll die X-Länge variabel sein; die y-Richtung jedoch nur eine fixe oder zwei fixe Größen annehmen (=nicht skaliert).
Vielen Dank für Eure Hilfe und Eurer Verständnis, bzgl. der falschen, technischen Ausdrucksweise. Ich freue mich über Eure Ratschläge.
ST ist eine Abkürzung für "Structured Text"
Das soll heissen, der Text kann (und sollte) strukturiert werden.
Dann ist das auch lesbar. Ich habe das im angehängten Projekt mal ausgeführt.
Wofür soll denn die REPEAT Anweisung in "Werkstueck_Verwalt" gut sein ?
Vor dem REPEAT machst du: VISU_WerksteuckNR_Eingabe_Speicherung:= VISU_WerksteuckNR_Eingabe;
Und REPEATEST dann so lange bis die beiden gleich sind ??? Da werden nicht viele Zyklen raus kommen.
Das selbe mit der untersten IF Anweisung.
Ob eine Schleife endlos ist oder nicht hat weder mit der Zykluszeit noch mit der Priorität was zu tun.
Die Schleife ist Endlos wenn die Austrittsbedingung nie erfüllt wird.
Warum hast du überhaupt verschiedene Tasks ? Das kann doch alles in einer gemacht werden.
Zitat:
Mein Problem ist nun, wenn ich die Variable "Stueck-Annahme" auf True setzte/force wird bei Priorität 5 die IF-Anweisung nicht ausgeführt, bei Priorität 2 klappt dies teilweise.
Das würde mir an deiner Stelle sehr zu denken geben.
Wie kann so etwas zustande kommen ? Und was hat das mit der Priorität zu tun ?
Vor allem wenns nur teilweise funktioniert !
Du solltest versuchen zu verstehen was passiert wenn eine Variable in verschiedenen Tasks benutzt und beidseitig geschrieben/gelesen wird.
Was passiert wenn ein Task den anderen aufgrund von Lauzeit / Priorität unterbricht ?
Solange du dir da nicht sicher bist, zurück zu 4.
Zitat:
2.Frage/Vereinfachung
Ich würde zu diesem Zweck ein ARRAY[30] of STRUCT benutzen.
Das ARRAY enthält die Anzahl der Werkstücke und die STRUCT die Parameter.
6.1.
Und du musst überhaupt nichts in die VISU "laden".
Du kannst die Elemente des ARRAYS direkt in der Visu anzeigen und auch beschreiben.
So was: >Zitat:
IF %IX8.14 = TRUE THEN
würde ich unter keinen Umständen benutzen !
Leg eine Boolsche Variable auf die Adresse, sonst musst du das an allen Stellen ändern wenn sich die Adresse mal verschiebt.
ACHTUNG: das Problem mit den Arrays für die Visu hat sich erledigt,
ich hatte diesen Programmteil viel zu umständlich erstellt, da mir nicht bewusst war, dass die Variabeln seitens Eingaben durch die Visu und vom Programm geändert werden können (mein Programm funktionierte so dann auch nicht),...
Die anderen Fragen sind noch aktuell, des Weiteren habe ich eine neue Antwort erstellt, bzgl. weiteren Vereinfachungen, siehe weiter unten.
Guten Morgen Erik,
Erik Böhm hat geschrieben:
Moin
1. ST ist eine Abkürzung für "Structured Text"
Das soll heissen, der Text kann (und sollte) strukturiert werden.
Dann ist das auch lesbar. Ich habe das im angehängten Projekt mal ausgeführt.
Jetzt, ist das Ganze auch übersichtlich:D
Erik Böhm hat geschrieben:
Moin
2. Wofür soll denn die REPEAT Anweisung in "Werkstueck_Verwalt" gut sein ?
Vor dem REPEAT machst du: VISU_WerksteuckNR_Eingabe_Speicherung:= VISU_WerksteuckNR_Eingabe;
Und REPEATEST dann so lange bis die beiden gleich sind ??? Da werden nicht viele Zyklen raus kommen.
Das selbe mit der untersten IF Anweisung.
In der Visuvalisierung (PLC_VISU) habe ich 5 Eingabefelder (Word-Variablen, [%s mm]) und mehrere boolsche "Taster" [Pfeile und Quadrate mit Nummmern].
Diese Eingabefelder und boolschen Taster können bei den bis zu 30 Werkstücken verschiedene Stellungen und Eingaben annehmen, die im jeweiligen Programm Werkstueck_1, Werksteuck_2, ... _30 benötigt und "gespeichert" werden müssen; zur weiteren Berechnung und falls vom Bediener wieder gewünscht, in die VISU geladen werden.
Wird das Werkstück 1 (blaues Rechteck in der PLC_VISU) angeglickt oder aber die Werkstücknummer bei den drei roten Fragezeichen eingegeben so sollen die mit den Werten aus dem Programm des angeklickten Werkstücks (z.B. 8 für Werksteuck_8) "beschrieben werden". Anschließend kann der Benutzer die Werte der Eingabefelder ändern oder boolschen Taster betätigen und dies wird sofort im Werksteuck_8 geändert;
Wird nun ein anderes Werkstüeck ausgewählt, so muss vom jeweiligen Programm (z.B. Werkstueck_5) die jeweiligen WErte wieder neu geladen werden und anschließend wieder in diesem Programm (z.B. Werkstueck_5) geschieben werden.
Ausgangslage, die Variable VISU_WerksteuckNR_Eingabe verändert sich, z.B. in 3 (durch Eingabe ??? = 3, in der VISU).
Zuerst werden die benötigen Variabeln aus dem Programm, hier im Beispiel: Werksteuck_3 [VISU_S1_SX_3] gelesen u und anschließend in der Visu angezeigt [VISU_S1_SX_NrX].
Durch die nachfolgende Gleichsetzung der internen Variable "VISU_WerksteuckNR_Eingabe_Speicherung", wird die Repeat-Schleife nur einmal durchlaufen und anschließend sorgt die IF-Schleife für die Aktualisierung, bei einer Eingabe in der Visu, der jeweiligen Variabeln im Programm Werksteuck_3 [VISU_S1_SX_3], bis sich die VISU_WerksteuckNR_Eingabe ändert.
.
VISU_WerksteuckNR_Eingabe_Speicherung:= VISU_WerksteuckNR_Eingabe;
CASE VISU_WerksteuckNR_Eingabe OF
1:
VISU_S1_SX_NrX := VISU_S1_SX_1;
VISU_Anfangswert_1_NrX := VISU_Anfangswert_1_WzSt_1; (vereinfacht mit nur zwei Variablen, insgesamt pro
Werkstück >10
2: ...
3:
VISU_S1_SX_NrX := VISU_S1_SX3;
VISU_Anfangswert_1_NrX := VISU_Anfangswert_1WzSt_3;
END_CASE
IF VISU_WerksteuckNR_Eingabe_Speicherung = VISU_WerksteuckNR_Eingabe THEN
CASE VISU_WerksteuckNR_Eingabe OF
1:
VISU_S1_SX_1 := VISU_S1_SX_NrX;
VISU_Anfangswert_1_WzSt_1; := VISU_Anfangswert_1_NrX ;
2: ...
3:
VISU_S1_SX3; := VISU_S1_SX_NrX;
VISU_Anfangswert_1WzSt_3;:= VISU_Anfangswert_1_NrX;
END_CASE END_IF
Wie kann man dies nun einfacher realisieren, bzw.
Zu diesem Auslesen/Anzeigen/Eingeben/Schreiben, oder wie auch immer
Nun kommt noch eine kleine Nebenbedingung hinzu: Die Werte, wie z.B. [VISU_S1_SX_3] müssen, wenn das Stück aktiviert wird (kein Zusammenhang mit der Visu, sondern eine interne Freigabe des Programms Werstueck_1), einmalig mit dem Wert der boolschen Eingabe in der PLC_VISU (rote Rechtecke, auch mit Zahlen, über dem langen grünen Rechteck) [VISU_Supp_1_AN_Allgm] " nur beschrieben werden" und weitere Werte (deklinierte Word-Variablen) werden genullt.
.
Erik Böhm hat geschrieben:
3. Ob eine Schleife endlos ist oder nicht hat weder mit der Zykluszeit noch mit der Priorität was zu tun.
Die Schleife ist Endlos wenn die Austrittsbedingung nie erfüllt wird.
Erik Böhm hat geschrieben:
4. Warum hast du überhaupt verschiedene Tasks ? Das kann doch alles in einer gemacht werden.
Ich dachte mir, wenn es die Möglichkeit, mit verschiedenen Prioritäten gibt, muss man diese auch nutzen,
Nein, ich habe einen Task der am Wichtigsten ist, da er für alle nachfolgenden Programme die Variabeln setzt/verändert.
Nachfolgend habe ich die Programme, die auf das Wichtigste Programm aufbauen.
Des Weiteren, mit geringster Priorität die Visu-Programme, mit einer Zykluszeit von 1s.
Mein Gedanke war, wenn die Visu-Programme mal übersprungen werden, wenn der Controller (Wago 750-881) mal mit den Programmen ausgelastet ist, sei das nicht so schlimm. Kommen die anderen Programme ins Stocken wäre dies weniger toll.
Und ich habe mir auch die Frage gestellt, wenn ich das Hauptrrogramm (Priorität 2) auf "Freilaufend" setze, ob dies dann "weniger oft" abgearbeitet wird, als Zyklisch t#50ms; bzw. wie man dies feststellen kann.
Die Werkstueck_x -Programme würde ich gerne nur "laufen lassen" wenn diese benötigt werden (Stueck5 = True); aber mit "Ereignisgesteuert" funktioniert dies wohl nicht,...
Ich weis nicht, ob meine Vorgehensweise nur ansatzweise richtig ist, bzw. wie und wann wählt man welche Einstellungen????
Erik Böhm hat geschrieben:
Das würde mir an deiner Stelle sehr zu denken geben.
Wie kann so etwas zustande kommen ? Und was hat das mit der Priorität zu tun ?
Vor allem wenns nur teilweise funktioniert !
Das heißt, die Tasks werden dann nicht vollständig durchlaufen; und somit dürfen keine Variabeln, die in zwei verschiedenen Programmen, mit unterschiedlichen Tasks, verwendet werden. Und bei der Variante VAR_IN und VAR_OUT ist das Problem auch nicht gelöst.
Brauch man für dieses kleine Programm (bis jetzt für 1 Werkstück für 1 Teilprogramm, nacher für 30 Werkstücke und 10 Teilprogramme) auf der 750-881 somit gar keine verschiedenen Prioritäten und Zyklenzeiten? Würde das Programm mit dann 30 Werkstücken und 10 Teilprogrammen um das fünfache ansteigen; wäre es dann von Nöten. Oder wieviel Zeilen/Anweisungen (was für Einheiten/Anweisungen) werden pro Sekunde abgearbeitet
Gibt es evtl. hierüber im Netz was zu lesen; über ST ist es schon sehr schwer, etwas zu finden?
Erik Böhm hat geschrieben:
Ich würde zu diesem Zweck ein ARRAY[30] of STRUCT benutzen.
Das ARRAY enthält die Anzahl der Werkstücke und die STRUCT die Parameter.
6.1.
Und du musst überhaupt nichts in die VISU "laden".
Du kannst die Elemente des ARRAYS direkt in der Visu anzeigen und auch beschreiben. [/quote]
Könntest Du mir bitte dies am oberen Beispiel erläutern. Und kann man eigentlich Arrays in einem weiteren Array verschachteln? Werden dann immer alle Werte des Arrays in einem Zyklus abgearbeitet und dauert dies länger, als wenn man es "ausprogrammiert"?
Erik Böhm hat geschrieben:
So was: würde ich unter keinen Umständen benutzen !
Leg eine Boolsche Variable auf die Adresse, sonst musst du das an allen Stellen ändern wenn sich die Adresse mal verschiebt.
Noch eine Frage zum Abschluss, wie kann ich im Programm [Werkstueck_Verwalt], die Variable [Steuckzahl_Nummer] beim Hochlauf des Controllers auf 1 setzten; ohne großen Aufwand?
Gruß Erik[/quote]
Danke, auch für die Zeit zum Lesen des ellen-langen Textes, von mir.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Voerst würde ich gerne wissen, kann man diesen nachfolgenden Programmteil (ersichtlich ist 1. und 2., wie gesagt es ginge bis 12.)vereinfachen (z.B. mit Arrays)?
Diese "Abschnitte" sollten jedoch immer parallel bzw. direkt nacheinander abgearbeitet werden, sofern z.B.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ich habe nun, das Ganze in ein Programm integriert, mit einanderverflochtene Arrays. Nun meine Frage, wie kann dieser Komplez am schnellsten abgearbeitet werden, sodass die Berechnung gleich schnell erfolgt, wie wenn man das ganze komplett ausführlich (12*20) aufgliedern würde.
MEines Erachtens ist nun ein Schleife mit:
1. Zähler 1-12 [Supp]
2. Zähler 1-20 [Werks]
einzufügen.
= [Werks]= 1, Zähler 1=+1: [Supp] 1,2,3,...12 , dann Zähler 2+1
dann
= [Werks]= 2, Zähler 1=+1: [Supp] 1,2,3,...12
...
= [Werks]= 12, Zähler 1=+1: [Supp] 1,2,3,...12, dann Zähler 1 und 2 = wieder Reset:1
[list=]Wäre dies so korrekt? Und was für eine Schleife oder wie wäre der Zählring auzubauen?
Wie sind die Tasks aufzubauen (freilaufend oder zyklisch? des weiteren sind noch andere Programmteile, die die gleiche Priorität haben sowie einige, die z.B. nur jede Sekunde ablaufen brauchen, vorhanden???[/list]
VAR_GLOBAL RETAIN PERSISTENT
IF1pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF1neg_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [0..12] OF BOOL;
IF2pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF2neg_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF3pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF4pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF4neg_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
S_ay2_Werks_ay1AN: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
VISU_SUP_ay1_MsNullp_: ARRAY [1..12] OF WORD; (Support 1-12 Maschienennullpunkt)
VISU_SUP_ay1_StRefp_: ARRAY [1..12] OF BYTE; (Support 1-12 Startrefernzpunkt vom Mittelpunkt des Supports + Bearbeitung)
VISU_SUP_ay1_EndRefp_: ARRAY [1..12] OF BYTE; (Support 1-12 Endtrefernzpunkt, vom Mittelpunkt des Supports + Bearbeitung)
VISU_SUP_ay1_Start_Sonder_: ARRAY [1..12] OF BYTE; (Support 1-12 Startrefernzpunkt, vom Mittelpunkt des Supports - SonderBearbeitung)
VISU_SUP_ay1_Ende_Sonder_: ARRAY [1..12] OF BYTE; (Support 1-12 Endtrefernzpunkt, vom Mittelpunkt des Supports - SonderBearbeitung) VISU_Anfangswert_1_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Anfangswert_1_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Bearbeitungswert_2_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Bearbeitungswert_2_ von Werkstueck 1-20 Bearbeitun; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Anfangswert_3_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Anfangswert_3_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Bearbeitungswert_4_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Bearbeitungswert_4_ von Werkstueck 1-20, keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Endwert_5_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Bearbeitungswert_5_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Stuecklaenge_: ARRAY [0..20] OF WORD; (Visu-Stuecklänge)
VISU_SUP_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL; (Support 1-12, für jeweiliges Werkstueck 1-20, Bearbeitung aktiv, Visuvalisierung Support Zustand Bearbeitung aktiv )
VISU_SUP_SONDERaktiv_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL; (Support 1, füR jeweiliges Werkstueck 1-20, Sonderlaengen-Bearbeitung aktiv, Visuvalisierung Support Zustand Sonderlaengen-Bearbeitung aktiv *)
END_VAR
FOR Werks:=1 TO 20 DO OR 1 TO (Stueckzahlnummer) FOR Supp:=1 TO 12 DO
Mal davon abgesehen daß ich deinen Quellcode immer noch nicht lesen kann weils totaler Spaghetti-Code ist, finde ich du gehst die Sache völlig überkompliziert an.
Wo ist denn das Problem ein 2 dimensionales ARRAY[0..20,1..12] in einer Schleife abzuarbeiten ?
FOR i:=1 TO 12 DO
FOR j:=1 TO 20 DO
axArrayName[i,j] := irgendwas;
END_FOR
END_FOR
Was denkst du wie lange das dauern wird ??? In der Zykluszeit wird das kaum bemerkbar sein. Ruf diesen Task im niedrigen ms Zyklus auf (z.B. 5ms) und fertig.
Freilaufende Tasks werden immer aufgerufen wenn kein anderer Task aktiv ist.
Das ist eher selten notwendig.
Die Daten würde ich immer noch in einer Struktur anlegen.
Also z.B.:
TYPE Visu :
STRUCT
Anfangswert_1_WzSt_: ARRAY [0..20] OF WORD;
Bearbeitungswert_2_WzSt_: ARRAY [0..20] OF WORD;
Anfangswert_3_WzSt_: ARRAY [0..20] OF WORD;
Bearbeitungswert_4_WzSt_: ARRAY [0..20] OF WORD;
Endwert_5_WzSt_: ARRAY [0..20] OF WORD;
Stuecklaenge_: ARRAY [0..20] OF WORD;
SUP_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL;
SUP_SONDERaktiv_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL;
END_STRUCT
END_TYPE
Deklaration des Arrays:
sVisu: ARRAY[1..12] of Visu.
Und warum du getrennte Datensätze für Visu und Ablauf benutzt erschließt sich mir auch nicht.
Wenn du sowieso willst dass die Daten sofort übernommen werden, warum schreibst du dann nicht direkt in die Daten rein ?
Erik Böhm hat geschrieben:
Moin
Mal davon abgesehen daß ich deinen Quellcode immer noch nicht lesen kann weils totaler Spaghetti-Code ist, finde ich du gehst die Sache völlig überkompliziert an.
Guten Morgen Erik, . Ich habe nun versucht im obrigen Beitrag den Spaghetti-Code zu entschlüsseln. Was meinst Du mit völlig uberkompliziert,
Erik Böhm hat geschrieben:
Wo ist denn das Problem ein 2 dimensionales ARRAY[0..20,1..12] in einer Schleife abzuarbeiten ?
FOR i:=1 TO 12 DO
FOR j:=1 TO 20 DO
axArrayName[i,j] := irgendwas;
END_FOR
END_FOR
Die For-Schleifen habe ich einfach mal über den kompletten "Programmteil" gelegt; ist dies so korrekt?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ja, für mein Empfinden ist das auch kompliziert. Ich denke du schießt mit Kanonen auf Spatzen.
Zu 1.
Eine Variable kann entweder direkt mit der Deklaration initialisiert werden, oder von Hand im Ablauf.
bInit: BOOL := FALSE;
Schau dir mal das Kapitel "Variablendeklaration" in der CoDeSys Hilfe an und für ARRAYs das Unterkapitel "Automatisch deklarieren"
Im Ablauf geht das einfach so:
IF NOT bInit THEN
( Hier allen Variablen Startwerte zuweisen. )
bInit := TRUE; ( Verhindert einen 2. Durchlauf )
END_IF
Zitat:
Die For-Schleifen habe ich einfach mal über den kompletten "Programmteil" gelegt; ist dies so korrekt?
Das hängt davon ab was du in der Schleife machst.
Alles was i und j nicht benutzt, macht keinen Sinn in der Schleife.
Wird dann eben 240 mal aufgerufen und macht immer das selbe.
Parallel läuft gar nichts. Im schlimmsten Fall würde der Task von einem höher Priorisierten unterbrochen und läuft dann beim nächsten Aufruf wieder von dort weiter wo unterbrochen wurde.
Siehe hierzu: "Taskkonfiguration" und "Welche Task wird bearbeitet?" in der Hilfe
Ich nehme mal eine die Schleife wird ca. eine 2 stellige Anzahl an µs benötigen. (Man beachte die Einheit µs)
Das kannst du z.B. durch einbinden der SysTaskInfo.lib erkennen.
Siehe: "Taskkonfiguration im Online Modus"
Zitat:
Blöde Frage: Dies wäre dann im zweiten Register von CoDeSys (in dem auch Rezepturen eingegebn werden?). Die beiden letzten Aussagen (Deklaration des Array und Zugriff) habe ich leider nicht verstanden, könntest Du mir dies bitte nochmal erläutern...
Ja, das wäre das Register Datentypen, das hat aber nichts mit Rezepturen zu tun.
Dafür gibts den Watch- und Rezepturverwalter (den ich dir übrigens sehr empfehlen kann).
Deklaration des Arrays:
Wenn du eine Struktur angelegt hast die alle Daten für einen Werkstücktyp enthält, dann musst du ja noch ein ARRAY dieser Struktur anlegen.
Das sieht dann so aus: sVisu: ARRAY[1..12] of Visu sVisu ist der Name des ARRAY of Visu. Visu ist der Name deiner neu angelegten Struktur.
Zugriff z.B:
Wenn du jetzt auf eine Lement dieses ARRAYs zugreifen willst, dann geht das mit Arrayname.Elementname[INDEX]
Also bei unserem Beispiel so:
Arrayname = sVisu
Elementame = Anfangswert_1_WzSt_
INDEX = 1
sVisu.Anfangswert_1_WzSt_[1]
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Erik Böhm hat geschrieben:
Hi
Ja, für mein Empfinden ist das auch kompliziert. Ich denke du schießt mit Kanonen auf Spatzen.
Zu 1.
Eine Variable kann entweder direkt mit der Deklaration initialisiert werden, oder von Hand im Ablauf.
bInit: BOOL := FALSE;
Schau dir mal das Kapitel "Variablendeklaration" in der CoDeSys Hilfe an und für ARRAYs das Unterkapitel "Automatisch deklarieren"
Im Ablauf geht das einfach so:
IF NOT bInit THEN
( Hier allen Variablen Startwerte zuweisen. )
bInit := TRUE; ( Verhindert einen 2. Durchlauf )
END_IF
Guten Morgen ERik,
danke für Deine Rückmeldung. Somit kann man wohl wirklich nur eine Variable statisch zuweisen oder aber mit einer IF-Schleife einmailg einen Startwert zukommen lassen.
Erik Böhm hat geschrieben:
2.
Das hängt davon ab was du in der Schleife machst.
Alles was i und j nicht benutzt, macht keinen Sinn in der Schleife.
Wird dann eben 240 mal aufgerufen und macht immer das selbe.
Da ja die erste IF-Bedinung darüber entscheidet, ist dies kein Problem, denn der Ganze Progrmmteil wird nur dnn bei True berechnet.
Erik Böhm hat geschrieben:
3. Parallel läuft gar nichts. Im schlimmsten Fall würde der Task von einem höher Priorisierten unterbrochen und läuft dann beim nächsten Aufruf wieder von dort weiter wo unterbrochen wurde.
Siehe hierzu: "Taskkonfiguration" und "Welche Task wird bearbeitet?" in der Hilfe
Ich nehme mal eine die Schleife wird ca. eine 2 stellige Anzahl an µs benötigen. (Man beachte die Einheit µs)
Das kannst du z.B. durch einbinden der SysTaskInfo.lib erkennen.
Siehe: "Taskkonfiguration im Online Modus"
Also ich habe nun mal, so wie ich das uben gemacht habe + am Ende/nach den Schleifen
WErt:=1 und WErt2:=1. Somit werden die ganze 240 Schleife innerhalb von 5ms durchlaufen und nicht in 1,2 Sekunden???
Diese Datei habe ich bereits gesucht, denn im Hilfe-Text war davon nie die Rede. Nun habe ich Sie implementiert; jedoch gibt es immer noch keine Anzeige, wie muss der Funktionsbaustein angesteuert werden? SysTaskInfo.lib
Erik Böhm hat geschrieben:
4.
Ja, das wäre das Register Datentypen, das hat aber nichts mit Rezepturen zu tun.
Dafür gibts den Watch- und Rezepturverwalter (den ich dir übrigens sehr empfehlen kann).
Deklaration des Arrays:
Wenn du eine Struktur angelegt hast die alle Daten für einen Werkstücktyp enthält, dann musst du ja noch ein ARRAY dieser Struktur anlegen.
Das sieht dann so aus: sVisu: ARRAY[1..12] of Visu sVisu ist der Name des ARRAY of Visu. Visu ist der Name deiner neu angelegten Struktur.
Also ich habe nun die Variabeln aus der globalen Variablenliste (nur die Arrays (wie Du oben aufgelistet hast)) in eine neue Stuktur kopiert. Das Programm läuft dann nicht mehr und gibt einen Fehler aus: END_Var fehlt in der Stuktur; ich habe jedoch gar kein Anfang gestzt,...??
Zugriff z.B: Des Weiteren meine Frage, wie kann ich diese Variablen "Resisten.. und Pariten,..t) als Bedingung hinzufügen (siehe globlae Variablen, beim Herunterfahren speichern)
Erik Böhm hat geschrieben:
Wenn du jetzt auf eine Lement dieses ARRAYs zugreifen willst, dann geht das mit Arrayname.Elementname[INDEX]
Also bei unserem Beispiel so:
Arrayname = sVisu
Elementame = Anfangswert_1_WzSt_
INDEX = 1
sVisu.Anfangswert_1_WzSt_[1]
Gruß Erik
Könntest Du mir dies bitte als Beispiel im Programm als Anhang speichern, das wäre sehr nett von Dir.
Des Weiteren habe ich auch das Problem mit der Alarm-Tabelle (diese hat bei anderen Programmen immer funktioniert) hier kommt teils beim Einloggen dann eine Fehlermeldung (von einer Bibliothek würde eine Variable fehlen). Sofern diese FEhelrmeldung weg ist und das Programm läuft (mit Datenbanken und in der Zielsystemeinstellung aktiviert) wird im PLC_VISu dennoch nichts angezeigt.
Über diese zwei Beispiele wäre ich Dir sehr dankbar; denn im Programm (als Beispiel) ist es für mich einfach verständlicher,....
Die SysTaskInfo.lib muss überhaupt nicht irgendwie angesteuert werden.
Das macht CoDeSys alles automatisch.
Wenn du nach einbinden der lib keine Anzeige hast, dann unterstützt dein Zielsystem das evtl. nicht.
Da musst du Wago fragen.
Um die Laufzeit der Schleife zu messen kannst du auch ganz einfach die Laufzeit messen.
Vor der Schleife
tStart: TIME;
tEnd: TIME;
tStart := TIME(); <- Das kopiert die aktuelle Systemzeit in die Variable tStart
nach der Schleife
tEnd := TIME();
Die Differenz der beiden ergibt die Laufzeit der Schleife. Ich tippe auf eine Differenz von 0ms.
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Erik Böhm hat geschrieben:
Mahlzeit
Kannst du bitte den aktuellen Stand noch hochladen ?
Dann kann ich den Fehler und die Beispiele direkt nachvollziehen.
Gruß
Erik
HAllo Erik,
werde ich gleich heute Abend machen.
Danke Dir.
Grüße
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ich hatte eigentlich heute früh schonmal geantwortet, aber das ist wohl irgendwie verloren gegangen...
Also nochmal:
Compilieren kann ich ohne Fehlermeldung.
Archiv des Projekts anbei. Da sind meine Libs alle mit drin, dann kannst du die falsche austauschen.
Du hast zwar einn Typ angelegt, aber nicht benutzt.
Sinn des ganzen ist eine gewisse Objektorientierung der Variablen.
Du erstellst also einen Typ (in diesem Fall VISU), der eine Struktur enthält die alle Eigenschaften des Werkstücks beschreibt.
Von diesem Typ machst du so viele Kopien wie du verschiedene Werkstückdefinitionen brauchst.
In deinem Fall momentan 20.
TYPE VISU:
STRUCT
Anfangswert_1_WzSt_: WORD; (Eingabe in Visu Anfangswert_1_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Bearbeitungswert_2_WzSt_: WORD; (Eingabe in Visu Bearbeitungswert_2_ von Werkstueck 1-20 Bearbeitun; Visuvalisierung Stueck-Berabeitungs-Laengen)
Anfangswert_3_WzSt_: WORD; (Eingabe in Visu Anfangswert_3_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Bearbeitungswert_4_WzSt_: WORD; (Eingabe in Visu Bearbeitungswert_4_ von Werkstueck 1-20, keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Endwert_5_WzSt_: WORD; (Eingabe in Visu Bearbeitungswert_5_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Stuecklaenge_: WORD; (Visu-Stuecklänge)
SUP_ay2_ST_ay1_: ARRAY[1..12]OF BOOL; (Support 1-12, für jeweiliges Werkstueck 1-20, Bearbeitung aktiv, Visuvalisierung Support Zustand Bearbeitung aktiv )
SUP_SONDERaktiv_ay2_ST_ay1_: ARRAY [1..12]OF BOOL; (Support 1, füR jeweiliges Werkstueck 1-20, Sonderlaengen-Bearbeitung aktiv, Visuvalisierung Support Zustand )
END_STRUCT
END_TYPE
Die 20 Kopien werden jetzt so gemacht:
sVisu: ARRAY[1..20] of VISU;
Wenn du jetzt auf eine Werkstückdefinition zugreifen willst, dann geht das so:
Wie du mehrdimensionale ARRAYs definierst ist Wurscht.
Ob so
aiTest: ARRAY[1..20,1..12] of INT;
oder so
aiTest: ARRAY[1..20] of ARRAY[1..12] of BOOL
Ich bevorzuge Variante 1, der Zugriff sieht dann so aus:
aiTest[1,1];
Laufzeit der Schleife.
Ich weiß ja nicht wie langsam deine bisherigen Steuerungen waren, aber ich gehe schwer davon aus daß die Schleife für die kompletten 240 Durchläufe nicht mehr als ein paar µs benötigt.
Mit der von mir beschriebenen Methode wirst du also immer auf eine Laufzeit von 0ms kommen, was ausreichend sein sollte...
Zitat:
Somit kann man wohl wirklich nur eine Variable statisch zuweisen oder aber mit einer IF-Schleife einmailg einen Startwert zukommen lassen.
Was denn sonst ? Dynamisch wirds vor der Laufzeit nicht gehen...
vielen Dank für die Einfügung des Konstukts, durch die Darstellung ist mir dies nun um einiges klarer geworden. Eine Mail habe ich Dir zukommen lassen.
Ich werde dies nach und nach übernehmen.
Nun habe ich noch das Problem mit der Alarm-Visu. (siehe eingebundene Alarmtabelle (PLC_VISU))
Könntest Du mir ein Beispiel mit der Bilbiothek erstellen, in das vorhandenen Projekt. Denn leider habe ich immer wieder eine Fehlermeldung mit Alarm...Bibliothek unvollständig.? Sollte dies dann nicht die Ursache sein, dann zeigt die Visu dennoch keinen Fehler an.
Vielen Danke und Grüße
CoDeSys
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Moin
Was hast du denn für ein Problem mit der Alarmliste ?
Im Beispiel kommt bei mir keine Fehlermeldung und in der Alarmkonfiguration steht auch nicht viel drin.
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Erik Böhm hat geschrieben:
Moin
Was hast du denn für ein Problem mit der Alarmliste ?
Im Beispiel kommt bei mir keine Fehlermeldung und in der Alarmkonfiguration steht auch nicht viel drin.
Gruß Erik
Hallo ERik,
eben das ist das Problem, gebe ich eine Fehlermeldung ein, gibt das Programm eine Fehlermeldung aus oder es passiert einfach gar nciht und es wird nichts angezeigt in der Visu.
Könntest Du mir bitte ein Beispiel erstellen.
Vielen Dank
GRüße
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ich habe mal wieder ein Anliegen mit den For-Schleifen.
Im Programm habe ich zwei Schleifen ineinander verschachtelt, DANK EURER HILFE, bzw. von Erik.
Start (einmalig beim Hochfahren des Controllers) IF Stueckzahlnummer = 0 Then [Werks]:=1; [Supp]:=1
[Werks]:=1; [Supp]:=1;1. For [Werks] 1 to 20 by 1 Do (oder so ähnlich)2. For [Supp] 1 to 12 by 1 DO END_FOR END_FOR
Nun erhalte ich bei einigen Variablen "invalid" und der Zähler wird mit 21 und 13 angegeben. Dies passiert nur, wenn die [Werks]:=1; [Supp]:=1 vor den Schleifen stehen; aber ich vermute mal das Programm zählt trotzdem bis 21???
ACHTUNG ich habe im Projekt [Werks]:=1; [Supp]:=1 zweimal eingefügt am Ende und am Anfang, eines sollte natürlich gelöscht werden.
Ob du die Variablen vor der FOR Schleife auf irgendeinen Wert setzt oder nicht macht keinen Unterschied.
FOR i := 1 to... setzt i schon auf 1. Was vorher drin stand ist wurscht.
Nun erhalte ich bei einigen Variablen "invalid" und der Zähler wird mit 21 und 13 angegeben.
Nach komplettem Durchlauf der Schleife steht der Zähler immer eins höher.
Das ist ja die Exit-Bedingung.
Die Anzeige 'Invalid' sagt dir nur, daß das ARRAY nur bis 20 geht, und der Index 21 nicht vorhanden ist.
Das ist alles völlig korrekt. Mach halt mal einen Breakpoint in der Schleife und steppe durch.
Dann wirst du sehen das alles wunderbar funktioniert (Wenn du die diversen Tippfehler behoben hast).
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Erik Böhm hat geschrieben:
Moin
1. Ob du die Variablen vor der FOR Schleife auf irgendeinen Wert setzt oder nicht macht keinen Unterschied.
FOR i := 1 to... setzt i schon auf 1. Was vorher drin stand ist wurscht.
2. Nun erhalte ich bei einigen Variablen "invalid" und der Zähler wird mit 21 und 13 angegeben.
Nach komplettem Durchlauf der Schleife steht der Zähler immer eins höher.
Das ist ja die Exit-Bedingung.
Die Anzeige 'Invalid' sagt dir nur, daß das ARRAY nur bis 20 geht, und der Index 21 nicht vorhanden ist.
Das ist alles völlig korrekt. Mach halt mal einen Breakpoint in der Schleife und steppe durch.
Dann wirst du sehen das alles wunderbar funktioniert (Wenn du die diversen Tippfehler behoben hast).
Gruß Erik
Hallo Erik,
was meinst Du (Wenn du die diversen Tippfehler behoben hast) mit?
Grüße und Danke
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Kriegst du keine Fehlermeldungen beim Übersetzen ?
Bei mir ist schon ein Aufruf in der Taskkonfiguration nicht mit einer schliessenden Klammer abgeschlossen.
Bei Werks :=1; fehlt der Strichpunkt
Und die Variable gleich drunter sollte korrekt VISU_Supp_Fas1_Toutch_7_8 heissen.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Guten Morgen miteinander,
Ich habe im beigefügten CoDeSys-Programm ein Programm "Werkstueck_Verwaltung" welches ich mit einem weiteren "Visu_Band" in einen und der eingefügt habe.
Mein Problem ist nun, wenn ich die Variable "Stueck-Annahme" auf True setzte/force wird bei Priorität 5 die IF-Anweisung nicht ausgeführt, bei Priorität 2 klappt dies teilweise.
-> Was habe ich falsch gemacht????
Auch in diesem Programm "WErkstueck_Verwalt" habe ich versucht, mit den zwei Case-Anwendungen Werte in die Visu zu schreiben und anschließend programminterne Variable wieder mit dem neuen, evtl. durch Eingabe, veränderten Wert, zu beschreiben. Kann man hier evtl. [i],.. arbeiten?
Das Ergebnis sollte sein, es gibt ca. 30 verschiedene Werkstücke mit jeweils ca. 12 Parametern (siehe 1. Zeile Case =vollständig), dass diese Variablen über die Visu geändert werden können.
Wird nun in der Visuvalisierung z.B. das Werkstück 15 aufgerufen, so sollen die 12 Parameter in die Visu PLC_VISU geladen werden (alle 12 Variabeln stammen aus z.B.Werkstueck_15 und werden auf die Variable ..._NrX geschrieben).
Wird nun der Wert über die nummerische Anzeige geändert oder boolsche_Elemente angeklickt, müssen anschließend die Änderungen oder einfach alle Parameter wieder in das Programm z.B. Werkstueck_15 geschrieben werden.
Ein Linienzug soll mit einem variablen Ende und einem fixen Ende in der Visu angezeigt werden. Wie ist dies möglich, denn das eine Ende darf sich nicht bewegen und das andere Ende bewegt sich lediglich in X-Richtung (Folge: Pfreillänge wird kleiner und gleichzeitg weißt diese dann immer wieder einen anderen Winkel auf +
Ein Viereck soll sich in x-richtung bewegen (realisiert) und gleichzeitg soll die X-Länge variabel sein; die y-Richtung jedoch nur eine fixe oder zwei fixe Größen annehmen (=nicht skaliert).
Vielen Dank für Eure Hilfe und Eurer Verständnis, bzgl. der falschen, technischen Ausdrucksweise. Ich freue mich über Eure Ratschläge.
Grüße
Codesys123456
Kantenautomat aktuell 5.pro [370.12 KiB]
Moin
ST ist eine Abkürzung für "Structured Text"
Das soll heissen, der Text kann (und sollte) strukturiert werden.
Dann ist das auch lesbar. Ich habe das im angehängten Projekt mal ausgeführt.
Wofür soll denn die REPEAT Anweisung in "Werkstueck_Verwalt" gut sein ?
Vor dem REPEAT machst du: VISU_WerksteuckNR_Eingabe_Speicherung:= VISU_WerksteuckNR_Eingabe;
Und REPEATEST dann so lange bis die beiden gleich sind ??? Da werden nicht viele Zyklen raus kommen.
Das selbe mit der untersten IF Anweisung.
Ob eine Schleife endlos ist oder nicht hat weder mit der Zykluszeit noch mit der Priorität was zu tun.
Die Schleife ist Endlos wenn die Austrittsbedingung nie erfüllt wird.
Warum hast du überhaupt verschiedene Tasks ? Das kann doch alles in einer gemacht werden.
Das würde mir an deiner Stelle sehr zu denken geben.
Wie kann so etwas zustande kommen ? Und was hat das mit der Priorität zu tun ?
Vor allem wenns nur teilweise funktioniert !
Du solltest versuchen zu verstehen was passiert wenn eine Variable in verschiedenen Tasks benutzt und beidseitig geschrieben/gelesen wird.
Was passiert wenn ein Task den anderen aufgrund von Lauzeit / Priorität unterbricht ?
Solange du dir da nicht sicher bist, zurück zu 4.
Ich würde zu diesem Zweck ein ARRAY[30] of STRUCT benutzen.
Das ARRAY enthält die Anzahl der Werkstücke und die STRUCT die Parameter.
6.1.
Und du musst überhaupt nichts in die VISU "laden".
Du kannst die Elemente des ARRAYS direkt in der Visu anzeigen und auch beschreiben.
IF %IX8.14 = TRUE THEN
würde ich unter keinen Umständen benutzen !
Leg eine Boolsche Variable auf die Adresse, sonst musst du das an allen Stellen ändern wenn sich die Adresse mal verschiebt.
Gruß Erik
Kantenautomat aktuell 5.pro [368.9 KiB]
ACHTUNG: das Problem mit den Arrays für die Visu hat sich erledigt,
ich hatte diesen Programmteil viel zu umständlich erstellt, da mir nicht bewusst war, dass die Variabeln seitens Eingaben durch die Visu und vom Programm geändert werden können (mein Programm funktionierte so dann auch nicht),...
Die anderen Fragen sind noch aktuell, des Weiteren habe ich eine neue Antwort erstellt, bzgl. weiteren Vereinfachungen, siehe weiter unten.
Guten Morgen Erik,
Jetzt, ist das Ganze auch übersichtlich:D
In der Visuvalisierung (PLC_VISU) habe ich 5 Eingabefelder (Word-Variablen, [%s mm]) und mehrere boolsche "Taster" [Pfeile und Quadrate mit Nummmern].
Diese Eingabefelder und boolschen Taster können bei den bis zu 30 Werkstücken verschiedene Stellungen und Eingaben annehmen, die im jeweiligen Programm Werkstueck_1, Werksteuck_2, ... _30 benötigt und "gespeichert" werden müssen; zur weiteren Berechnung und falls vom Bediener wieder gewünscht, in die VISU geladen werden.
Wird das Werkstück 1 (blaues Rechteck in der PLC_VISU) angeglickt oder aber die Werkstücknummer bei den drei roten Fragezeichen eingegeben so sollen die mit den Werten aus dem Programm des angeklickten Werkstücks (z.B. 8 für Werksteuck_8) "beschrieben werden". Anschließend kann der Benutzer die Werte der Eingabefelder ändern oder boolschen Taster betätigen und dies wird sofort im Werksteuck_8 geändert;
Wird nun ein anderes Werkstüeck ausgewählt, so muss vom jeweiligen Programm (z.B. Werkstueck_5) die jeweiligen WErte wieder neu geladen werden und anschließend wieder in diesem Programm (z.B. Werkstueck_5) geschieben werden.
Ausgangslage, die Variable VISU_WerksteuckNR_Eingabe verändert sich, z.B. in 3 (durch Eingabe ??? = 3, in der VISU).
Zuerst werden die benötigen Variabeln aus dem Programm, hier im Beispiel: Werksteuck_3 [VISU_S1_SX_3] gelesen u und anschließend in der Visu angezeigt [VISU_S1_SX_NrX].
Durch die nachfolgende Gleichsetzung der internen Variable "VISU_WerksteuckNR_Eingabe_Speicherung", wird die Repeat-Schleife nur einmal durchlaufen und anschließend sorgt die IF-Schleife für die Aktualisierung, bei einer Eingabe in der Visu, der jeweiligen Variabeln im Programm Werksteuck_3 [VISU_S1_SX_3], bis sich die VISU_WerksteuckNR_Eingabe ändert.
.
VISU_WerksteuckNR_Eingabe_Speicherung:= VISU_WerksteuckNR_Eingabe;
CASE VISU_WerksteuckNR_Eingabe OF
1:
VISU_S1_SX_NrX := VISU_S1_SX_1;
VISU_Anfangswert_1_NrX := VISU_Anfangswert_1_WzSt_1; (vereinfacht mit nur zwei Variablen, insgesamt pro
Werkstück >10
2: ...
3:
VISU_S1_SX_NrX := VISU_S1_SX3;
VISU_Anfangswert_1_NrX := VISU_Anfangswert_1WzSt_3;
END_CASE
IF VISU_WerksteuckNR_Eingabe_Speicherung = VISU_WerksteuckNR_Eingabe THEN
CASE VISU_WerksteuckNR_Eingabe OF
1:
VISU_S1_SX_1 := VISU_S1_SX_NrX;
VISU_Anfangswert_1_WzSt_1; := VISU_Anfangswert_1_NrX ;
2: ...
3:
VISU_S1_SX3; := VISU_S1_SX_NrX;
VISU_Anfangswert_1WzSt_3;:= VISU_Anfangswert_1_NrX;
END_CASE END_IF
Wie kann man dies nun einfacher realisieren, bzw.
Zu diesem Auslesen/Anzeigen/Eingeben/Schreiben, oder wie auch immer
Nun kommt noch eine kleine Nebenbedingung hinzu: Die Werte, wie z.B. [VISU_S1_SX_3] müssen, wenn das Stück aktiviert wird (kein Zusammenhang mit der Visu, sondern eine interne Freigabe des Programms Werstueck_1), einmalig mit dem Wert der boolschen Eingabe in der PLC_VISU (rote Rechtecke, auch mit Zahlen, über dem langen grünen Rechteck) [VISU_Supp_1_AN_Allgm] " nur beschrieben werden" und weitere Werte (deklinierte Word-Variablen) werden genullt.
.
R_TRIG(CLK: Stueck_3_aktiv , Q=
VISU_S1_SX_3 := VISU_Supp_1_AN_Allgm;
VISU_Anfangswert_1_WzSt_3 := 0)
Ich dachte mir, wenn es die Möglichkeit, mit verschiedenen Prioritäten gibt, muss man diese auch nutzen,
Nein, ich habe einen Task der am Wichtigsten ist, da er für alle nachfolgenden Programme die Variabeln setzt/verändert.
Nachfolgend habe ich die Programme, die auf das Wichtigste Programm aufbauen.
Des Weiteren, mit geringster Priorität die Visu-Programme, mit einer Zykluszeit von 1s.
Mein Gedanke war, wenn die Visu-Programme mal übersprungen werden, wenn der Controller (Wago 750-881) mal mit den Programmen ausgelastet ist, sei das nicht so schlimm. Kommen die anderen Programme ins Stocken wäre dies weniger toll.
Und ich habe mir auch die Frage gestellt, wenn ich das Hauptrrogramm (Priorität 2) auf "Freilaufend" setze, ob dies dann "weniger oft" abgearbeitet wird, als Zyklisch t#50ms; bzw. wie man dies feststellen kann.
Die Werkstueck_x -Programme würde ich gerne nur "laufen lassen" wenn diese benötigt werden (Stueck5 = True); aber mit "Ereignisgesteuert" funktioniert dies wohl nicht,...
Ich weis nicht, ob meine Vorgehensweise nur ansatzweise richtig ist, bzw. wie und wann wählt man welche Einstellungen????
Wie kann so etwas zustande kommen ? Und was hat das mit der Priorität zu tun ?
Vor allem wenns nur teilweise funktioniert !
Das heißt, die Tasks werden dann nicht vollständig durchlaufen; und somit dürfen keine Variabeln, die in zwei verschiedenen Programmen, mit unterschiedlichen Tasks, verwendet werden. Und bei der Variante VAR_IN und VAR_OUT ist das Problem auch nicht gelöst.
Brauch man für dieses kleine Programm (bis jetzt für 1 Werkstück für 1 Teilprogramm, nacher für 30 Werkstücke und 10 Teilprogramme) auf der 750-881 somit gar keine verschiedenen Prioritäten und Zyklenzeiten? Würde das Programm mit dann 30 Werkstücken und 10 Teilprogrammen um das fünfache ansteigen; wäre es dann von Nöten. Oder wieviel Zeilen/Anweisungen (was für Einheiten/Anweisungen) werden pro Sekunde abgearbeitet
Gibt es evtl. hierüber im Netz was zu lesen; über ST ist es schon sehr schwer, etwas zu finden?
Das ARRAY enthält die Anzahl der Werkstücke und die STRUCT die Parameter.
6.1.
Und du musst überhaupt nichts in die VISU "laden".
Du kannst die Elemente des ARRAYS direkt in der Visu anzeigen und auch beschreiben.
[/quote]
Könntest Du mir bitte dies am oberen Beispiel erläutern. Und kann man eigentlich Arrays in einem weiteren Array verschachteln? Werden dann immer alle Werte des Arrays in einem Zyklus abgearbeitet und dauert dies länger, als wenn man es "ausprogrammiert"?
Leg eine Boolsche Variable auf die Adresse, sonst musst du das an allen Stellen ändern wenn sich die Adresse mal verschiebt.
Noch eine Frage zum Abschluss, wie kann ich im Programm [Werkstueck_Verwalt], die Variable [Steuckzahl_Nummer] beim Hochlauf des Controllers auf 1 setzten; ohne großen Aufwand?
Gruß Erik[/quote]
Danke, auch für die Zeit zum Lesen des ellen-langen Textes, von mir.
HAllo miteinander,
Voerst würde ich gerne wissen, kann man diesen nachfolgenden Programmteil (ersichtlich ist 1. und 2., wie gesagt es ginge bis 12.)vereinfachen (z.B. mit Arrays)?
Diese "Abschnitte" sollten jedoch immer parallel bzw. direkt nacheinander abgearbeitet werden, sofern z.B.
Hallo miteinander,
ich habe nun, das Ganze in ein Programm integriert, mit einanderverflochtene Arrays. Nun meine Frage, wie kann dieser Komplez am schnellsten abgearbeitet werden, sodass die Berechnung gleich schnell erfolgt, wie wenn man das ganze komplett ausführlich (12*20) aufgliedern würde.
MEines Erachtens ist nun ein Schleife mit:
1. Zähler 1-12 [Supp]
2. Zähler 1-20 [Werks]
einzufügen.
= [Werks]= 1, Zähler 1=+1: [Supp] 1,2,3,...12 , dann Zähler 2+1
dann
= [Werks]= 2, Zähler 1=+1: [Supp] 1,2,3,...12
...
= [Werks]= 12, Zähler 1=+1: [Supp] 1,2,3,...12, dann Zähler 1 und 2 = wieder Reset:1
[list=]Wäre dies so korrekt? Und was für eine Schleife oder wie wäre der Zählring auzubauen?
Wie sind die Tasks aufzubauen (freilaufend oder zyklisch? des weiteren sind noch andere Programmteile, die die gleiche Priorität haben sowie einige, die z.B. nur jede Sekunde ablaufen brauchen, vorhanden???[/list]
VAR_GLOBAL RETAIN PERSISTENT
IF1pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF1neg_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [0..12] OF BOOL;
IF2pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF2neg_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF3pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF4pos_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
IF4neg_Supp_ay2_vWerk_ay1_On: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
S_ay2_Werks_ay1AN: ARRAY [0..20] OF ARRAY [1..12] OF BOOL;
VISU_SUP_ay1_MsNullp_: ARRAY [1..12] OF WORD; (Support 1-12 Maschienennullpunkt)
VISU_SUP_ay1_StRefp_: ARRAY [1..12] OF BYTE; (Support 1-12 Startrefernzpunkt vom Mittelpunkt des Supports + Bearbeitung)
VISU_SUP_ay1_EndRefp_: ARRAY [1..12] OF BYTE; (Support 1-12 Endtrefernzpunkt, vom Mittelpunkt des Supports + Bearbeitung)
VISU_SUP_ay1_Start_Sonder_: ARRAY [1..12] OF BYTE; (Support 1-12 Startrefernzpunkt, vom Mittelpunkt des Supports - SonderBearbeitung)
VISU_SUP_ay1_Ende_Sonder_: ARRAY [1..12] OF BYTE; (Support 1-12 Endtrefernzpunkt, vom Mittelpunkt des Supports - SonderBearbeitung) VISU_Anfangswert_1_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Anfangswert_1_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Bearbeitungswert_2_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Bearbeitungswert_2_ von Werkstueck 1-20 Bearbeitun; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Anfangswert_3_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Anfangswert_3_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Bearbeitungswert_4_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Bearbeitungswert_4_ von Werkstueck 1-20, keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Endwert_5_WzSt_: ARRAY [0..20] OF WORD; (Eingabe in Visu Bearbeitungswert_5_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
VISU_Stuecklaenge_: ARRAY [0..20] OF WORD; (Visu-Stuecklänge)
VISU_SUP_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL; (Support 1-12, für jeweiliges Werkstueck 1-20, Bearbeitung aktiv, Visuvalisierung Support Zustand Bearbeitung aktiv )
VISU_SUP_SONDERaktiv_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL; (Support 1, füR jeweiliges Werkstueck 1-20, Sonderlaengen-Bearbeitung aktiv, Visuvalisierung Support Zustand Sonderlaengen-Bearbeitung aktiv *)
END_VAR
FOR Werks:=1 TO 20 DO OR 1 TO (Stueckzahlnummer)
FOR Supp:=1 TO 12 DO
END_FOR
END_FOR
Kantenautomat aktuell 6.pro [429.75 KiB]
Related
Talk.ru: 1
Moin
Mal davon abgesehen daß ich deinen Quellcode immer noch nicht lesen kann weils totaler Spaghetti-Code ist, finde ich du gehst die Sache völlig überkompliziert an.
Wo ist denn das Problem ein 2 dimensionales ARRAY[0..20,1..12] in einer Schleife abzuarbeiten ?
FOR i:=1 TO 12 DO
FOR j:=1 TO 20 DO
axArrayName[i,j] := irgendwas;
END_FOR
END_FOR
Was denkst du wie lange das dauern wird ??? In der Zykluszeit wird das kaum bemerkbar sein. Ruf diesen Task im niedrigen ms Zyklus auf (z.B. 5ms) und fertig.
Freilaufende Tasks werden immer aufgerufen wenn kein anderer Task aktiv ist.
Das ist eher selten notwendig.
Die Daten würde ich immer noch in einer Struktur anlegen.
Also z.B.:
TYPE Visu :
STRUCT
Anfangswert_1_WzSt_: ARRAY [0..20] OF WORD;
Bearbeitungswert_2_WzSt_: ARRAY [0..20] OF WORD;
Anfangswert_3_WzSt_: ARRAY [0..20] OF WORD;
Bearbeitungswert_4_WzSt_: ARRAY [0..20] OF WORD;
Endwert_5_WzSt_: ARRAY [0..20] OF WORD;
Stuecklaenge_: ARRAY [0..20] OF WORD;
SUP_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL;
SUP_SONDERaktiv_ay2_ST_ay1_: ARRAY [0..20]OF ARRAY [1..12]OF BOOL;
END_STRUCT
END_TYPE
Deklaration des Arrays:
sVisu: ARRAY[1..12] of Visu.
Zugriff z.B:
sVisu.Anfangswert_1_WzSt_[1]
Und warum du getrennte Datensätze für Visu und Ablauf benutzt erschließt sich mir auch nicht.
Wenn du sowieso willst dass die Daten sofort übernommen werden, warum schreibst du dann nicht direkt in die Daten rein ?
Gruß Erik
Related
Talk.ru: 1
Guten Morgen Erik, . Ich habe nun versucht im obrigen Beitrag den Spaghetti-Code zu entschlüsseln. Was meinst Du mit völlig uberkompliziert,
Die For-Schleifen habe ich einfach mal über den kompletten "Programmteil" gelegt; ist dies so korrekt?
Hi
Ja, für mein Empfinden ist das auch kompliziert. Ich denke du schießt mit Kanonen auf Spatzen.
Zu 1.
Eine Variable kann entweder direkt mit der Deklaration initialisiert werden, oder von Hand im Ablauf.
bInit: BOOL := FALSE;
Schau dir mal das Kapitel "Variablendeklaration" in der CoDeSys Hilfe an und für ARRAYs das Unterkapitel "Automatisch deklarieren"
Im Ablauf geht das einfach so:
IF NOT bInit THEN
( Hier allen Variablen Startwerte zuweisen. )
bInit := TRUE; ( Verhindert einen 2. Durchlauf )
END_IF
Das hängt davon ab was du in der Schleife machst.
Alles was i und j nicht benutzt, macht keinen Sinn in der Schleife.
Wird dann eben 240 mal aufgerufen und macht immer das selbe.
Siehe hierzu: "Taskkonfiguration" und "Welche Task wird bearbeitet?" in der Hilfe
Ich nehme mal eine die Schleife wird ca. eine 2 stellige Anzahl an µs benötigen. (Man beachte die Einheit µs)
Das kannst du z.B. durch einbinden der SysTaskInfo.lib erkennen.
Siehe: "Taskkonfiguration im Online Modus"
Ja, das wäre das Register Datentypen, das hat aber nichts mit Rezepturen zu tun.
Dafür gibts den Watch- und Rezepturverwalter (den ich dir übrigens sehr empfehlen kann).
Deklaration des Arrays:
Wenn du eine Struktur angelegt hast die alle Daten für einen Werkstücktyp enthält, dann musst du ja noch ein ARRAY dieser Struktur anlegen.
Das sieht dann so aus: sVisu: ARRAY[1..12] of Visu sVisu ist der Name des ARRAY of Visu. Visu ist der Name deiner neu angelegten Struktur.
Zugriff z.B:
Wenn du jetzt auf eine Lement dieses ARRAYs zugreifen willst, dann geht das mit Arrayname.Elementname[INDEX]
Also bei unserem Beispiel so:
Arrayname = sVisu
Elementame = Anfangswert_1_WzSt_
INDEX = 1
sVisu.Anfangswert_1_WzSt_[1]
Gruß Erik
Guten Morgen ERik,
danke für Deine Rückmeldung. Somit kann man wohl wirklich nur eine Variable statisch zuweisen oder aber mit einer IF-Schleife einmailg einen Startwert zukommen lassen.
Da ja die erste IF-Bedinung darüber entscheidet, ist dies kein Problem, denn der Ganze Progrmmteil wird nur dnn bei True berechnet.
Also ich habe nun mal, so wie ich das uben gemacht habe + am Ende/nach den Schleifen
WErt:=1 und WErt2:=1.
Somit werden die ganze 240 Schleife innerhalb von 5ms durchlaufen und nicht in 1,2 Sekunden???
Diese Datei habe ich bereits gesucht, denn im Hilfe-Text war davon nie die Rede. Nun habe ich Sie implementiert; jedoch gibt es immer noch keine Anzeige, wie muss der Funktionsbaustein angesteuert werden? SysTaskInfo.lib
Also ich habe nun die Variabeln aus der globalen Variablenliste (nur die Arrays (wie Du oben aufgelistet hast)) in eine neue Stuktur kopiert. Das Programm läuft dann nicht mehr und gibt einen Fehler aus: END_Var fehlt in der Stuktur; ich habe jedoch gar kein Anfang gestzt,...??
Zugriff z.B:
Des Weiteren meine Frage, wie kann ich diese Variablen "Resisten.. und Pariten,..t) als Bedingung hinzufügen (siehe globlae Variablen, beim Herunterfahren speichern)
Könntest Du mir dies bitte als Beispiel im Programm als Anhang speichern, das wäre sehr nett von Dir.
Des Weiteren habe ich auch das Problem mit der Alarm-Tabelle (diese hat bei anderen Programmen immer funktioniert) hier kommt teils beim Einloggen dann eine Fehlermeldung (von einer Bibliothek würde eine Variable fehlen). Sofern diese FEhelrmeldung weg ist und das Programm läuft (mit Datenbanken und in der Zielsystemeinstellung aktiviert) wird im PLC_VISu dennoch nichts angezeigt.
Über diese zwei Beispiele wäre ich Dir sehr dankbar; denn im Programm (als Beispiel) ist es für mich einfach verständlicher,....
DAnke Dir sehr.
Grüße
Andreas
Related
Talk.ru: 1
Mahlzeit
Kannst du bitte den aktuellen Stand noch hochladen ?
Dann kann ich den Fehler und die Beispiele direkt nachvollziehen.
Gruß
Erik
Nochmal Hi
Die SysTaskInfo.lib muss überhaupt nicht irgendwie angesteuert werden.
Das macht CoDeSys alles automatisch.
Wenn du nach einbinden der lib keine Anzeige hast, dann unterstützt dein Zielsystem das evtl. nicht.
Da musst du Wago fragen.
Um die Laufzeit der Schleife zu messen kannst du auch ganz einfach die Laufzeit messen.
Vor der Schleife
tStart: TIME;
tEnd: TIME;
tStart := TIME(); <- Das kopiert die aktuelle Systemzeit in die Variable tStart
nach der Schleife
tEnd := TIME();
Die Differenz der beiden ergibt die Laufzeit der Schleife. Ich tippe auf eine Differenz von 0ms.
Gruß Erik
HAllo Erik,
werde ich gleich heute Abend machen.
Danke Dir.
Grüße
Anbei nun die Zwischenversion,...
Viele Grüße und bitte entschuldige das Durcheinander. bin gerade am sortieren der Variablen,...
Kantenautomat aktuell 7.pro [385.08 KiB]
Mahlzeit
Ich hatte eigentlich heute früh schonmal geantwortet, aber das ist wohl irgendwie verloren gegangen...
Also nochmal:
Compilieren kann ich ohne Fehlermeldung.
Archiv des Projekts anbei. Da sind meine Libs alle mit drin, dann kannst du die falsche austauschen.
Du hast zwar einn Typ angelegt, aber nicht benutzt.
Sinn des ganzen ist eine gewisse Objektorientierung der Variablen.
Du erstellst also einen Typ (in diesem Fall VISU), der eine Struktur enthält die alle Eigenschaften des Werkstücks beschreibt.
Von diesem Typ machst du so viele Kopien wie du verschiedene Werkstückdefinitionen brauchst.
In deinem Fall momentan 20.
TYPE VISU:
STRUCT
Anfangswert_1_WzSt_: WORD; (Eingabe in Visu Anfangswert_1_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Bearbeitungswert_2_WzSt_: WORD; (Eingabe in Visu Bearbeitungswert_2_ von Werkstueck 1-20 Bearbeitun; Visuvalisierung Stueck-Berabeitungs-Laengen)
Anfangswert_3_WzSt_: WORD; (Eingabe in Visu Anfangswert_3_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Bearbeitungswert_4_WzSt_: WORD; (Eingabe in Visu Bearbeitungswert_4_ von Werkstueck 1-20, keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Endwert_5_WzSt_: WORD; (Eingabe in Visu Bearbeitungswert_5_ von Werkstueck 1-20 keine Bearbeitung; Visuvalisierung Stueck-Berabeitungs-Laengen)
Stuecklaenge_: WORD; (Visu-Stuecklänge)
SUP_ay2_ST_ay1_: ARRAY[1..12]OF BOOL; (Support 1-12, für jeweiliges Werkstueck 1-20, Bearbeitung aktiv, Visuvalisierung Support Zustand Bearbeitung aktiv )
SUP_SONDERaktiv_ay2_ST_ay1_: ARRAY [1..12]OF BOOL; (Support 1, füR jeweiliges Werkstueck 1-20, Sonderlaengen-Bearbeitung aktiv, Visuvalisierung Support Zustand )
END_STRUCT
END_TYPE
Die 20 Kopien werden jetzt so gemacht:
sVisu: ARRAY[1..20] of VISU;
Wenn du jetzt auf eine Werkstückdefinition zugreifen willst, dann geht das so:
sVisu[1].SUP_ay2_ST_ay1_[1];
Ob so
aiTest: ARRAY[1..20,1..12] of INT;
oder so
aiTest: ARRAY[1..20] of ARRAY[1..12] of BOOL
Ich bevorzuge Variante 1, der Zugriff sieht dann so aus:
aiTest[1,1];
Laufzeit der Schleife.
Ich weiß ja nicht wie langsam deine bisherigen Steuerungen waren, aber ich gehe schwer davon aus daß die Schleife für die kompletten 240 Durchläufe nicht mehr als ein paar µs benötigt.
Mit der von mir beschriebenen Methode wirst du also immer auf eine Laufzeit von 0ms kommen, was ausreichend sein sollte...
Was denn sonst ? Dynamisch wirds vor der Laufzeit nicht gehen...
Gruß Erik
Kantenautomat aktuell 7 EB.zip [96.44 KiB]
Related
Talk.ru: 1
Du könntest mir auch ne mail an: e erik.boehm@asys.de e schreiben, dann schick ich dir mal meine Telefonnummer zurück.
Guten Morgen Erik,
vielen Dank für die Einfügung des Konstukts, durch die Darstellung ist mir dies nun um einiges klarer geworden. Eine Mail habe ich Dir zukommen lassen.
Ich werde dies nach und nach übernehmen.
Nun habe ich noch das Problem mit der Alarm-Visu. (siehe eingebundene Alarmtabelle (PLC_VISU))
Könntest Du mir ein Beispiel mit der Bilbiothek erstellen, in das vorhandenen Projekt. Denn leider habe ich immer wieder eine Fehlermeldung mit Alarm...Bibliothek unvollständig.? Sollte dies dann nicht die Ursache sein, dann zeigt die Visu dennoch keinen Fehler an.
Vielen Danke und Grüße
CoDeSys
Moin
Was hast du denn für ein Problem mit der Alarmliste ?
Im Beispiel kommt bei mir keine Fehlermeldung und in der Alarmkonfiguration steht auch nicht viel drin.
Gruß Erik
Hallo ERik,
eben das ist das Problem, gebe ich eine Fehlermeldung ein, gibt das Programm eine Fehlermeldung aus oder es passiert einfach gar nciht und es wird nichts angezeigt in der Visu.
Könntest Du mir bitte ein Beispiel erstellen.
Vielen Dank
GRüße
Guten Morgen miteinander,
ich habe mal wieder ein Anliegen mit den For-Schleifen.
Im Programm habe ich zwei Schleifen ineinander verschachtelt, DANK EURER HILFE, bzw. von Erik.
Start (einmalig beim Hochfahren des Controllers) IF Stueckzahlnummer = 0 Then [Werks]:=1; [Supp]:=1
[Werks]:=1; [Supp]:=1;1. For [Werks] 1 to 20 by 1 Do (oder so ähnlich)2. For [Supp] 1 to 12 by 1 DO END_FOR END_FOR
Nun erhalte ich bei einigen Variablen "invalid" und der Zähler wird mit 21 und 13 angegeben. Dies passiert nur, wenn die [Werks]:=1; [Supp]:=1 vor den Schleifen stehen; aber ich vermute mal das Programm zählt trotzdem bis 21???
ACHTUNG ich habe im Projekt [Werks]:=1; [Supp]:=1 zweimal eingefügt am Ende und am Anfang, eines sollte natürlich gelöscht werden.
Danke und GRüße
Kantenautomat aktuell 9.pro [408.71 KiB]
Moin
Ob du die Variablen vor der FOR Schleife auf irgendeinen Wert setzt oder nicht macht keinen Unterschied.
FOR i := 1 to... setzt i schon auf 1. Was vorher drin stand ist wurscht.
Nun erhalte ich bei einigen Variablen "invalid" und der Zähler wird mit 21 und 13 angegeben.
Nach komplettem Durchlauf der Schleife steht der Zähler immer eins höher.
Das ist ja die Exit-Bedingung.
Die Anzeige 'Invalid' sagt dir nur, daß das ARRAY nur bis 20 geht, und der Index 21 nicht vorhanden ist.
Das ist alles völlig korrekt. Mach halt mal einen Breakpoint in der Schleife und steppe durch.
Dann wirst du sehen das alles wunderbar funktioniert (Wenn du die diversen Tippfehler behoben hast).
Gruß Erik
Hallo Erik,
was meinst Du (Wenn du die diversen Tippfehler behoben hast) mit?
Grüße und Danke
Kriegst du keine Fehlermeldungen beim Übersetzen ?
Bei mir ist schon ein Aufruf in der Taskkonfiguration nicht mit einer schliessenden Klammer abgeschlossen.
Bei Werks :=1; fehlt der Strichpunkt
Und die Variable gleich drunter sollte korrekt VISU_Supp_Fas1_Toutch_7_8 heissen.