TIA Ein Array "Position [0..53] of Int" wobei in jedem Index 2 Werte sein sollen

Dieter_654

Level-1
Beiträge
4
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo liebe SPS-Community,

ich möchte in meiner HMI eine Position aus dem Array "Position [0..53]" auswählen, zum Beispiel den Index [4].

In diesem Index sollten eine x- und eine y-Position stehen. Eine Liftanlage fährt dann diese Position direkt an.

Sollte man hierfür UDTs verwenden, oder gibt es eine andere Lösung?

Vielen lieben Dank.
 
Hallo,

ich würde mit einem UDT arbeiten:
Array[0..53] of UDT

Alternativ:
Array[0..53, 0..1] of DInt

Vergiss nicht den Index vom HMI auf Plausibilität abzufragen.

Gruß
 
Die UDT-Variante hat den angenehmen Vorteil, dass "sprechende Variablennamen" verwendet werden können.

Statt "Array[4,1]" hättest du dann "Array[4].PosX". Außerdem könnten dann durch Erweitern des UDTs noch zusätzliche Informationen dazukommen, die nicht vom Typ DInt sein müssen (Positionsname, Messwerte als Real, etc.)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die UDT-Variante hat den angenehmen Vorteil, dass "sprechende Variablennamen" verwendet werden können.

Statt "Array[4,1]" hättest du dann "Array[4].PosX". Außerdem könnten dann durch Erweitern des UDTs noch zusätzliche Informationen dazukommen, die nicht vom Typ DInt sein müssen (Positionsname, Messwerte als Real, etc.)
Screenshot 2024-07-04 140453.png

So mache ich das immer. Ein UDT den ich dann als Array mit einer Konstante aufrufe. Inklusive einem Bit das mir ausgibt, ob die Achse in der jeweiligen Position steht und ein Freigabe Signal für die jeweilige Position zum verriegeln
 
Wenn du "AXIS_POS_MAX" auf 9 setzt, verwendest du dann 9 oder 10 verschiedene Achsen-Positionen?
9, meine Arrays beginne ich immer bei 0.. nicht das irgendwann mal was überschwappt wenn ich doch mal eine Schleife brauche, oder so. Die Arrays im Screenshot werden tatsächlich für eine Schleife verwendet: InPosition Auswertung und fürs HMI, da hab ich dann ein Dropdown Menü wo ich die Positionen auswählen kann, je nach Wert des E/A Feldes wird dann die bestimmte Position eben umkopiert
 
Also wird X[0] nicht verwendet, sondern ist nur gegen Schleifenzugriffsfehler vorhanden?
Yes. Es sind keine Startwerte eingetragen und taucht auch nicht in der Textliste im HMI auf.

Kannst natürlich nicht verhindern, dass ich mal so blöd bin und auf Pos 0 im Automatikablauf schreibe, dann regt sich aber nichts weil der Interlock nicht TRUE ist
 
Also wird X[0] nicht verwendet, sondern ist nur gegen Schleifenzugriffsfehler vorhanden?
Ich nehme Index 0 immer als "leeren UDT", also mit Startwerten.
Spart Aufwand wenn man einen kompletten, großen UDT mit Startwerten belegen will.
Und zumindes Siemens Comfort-HMIs können nicht mit einem [1..10] umgehen & machen deswegen automatisch auf HMI-Seite ein [0..9] daraus.
Kann in der Hektik einer Inbetriebnahme zu ganz blöden Flüchtigkeitsfehlern führen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also wird X[0] nicht verwendet, sondern ist nur gegen Schleifenzugriffsfehler vorhanden?
Wenn du mit Siemens TIA HMI auf das Array zugreifen willst, das kann als Array nur Array [0..x], egal wie das Array in der CPU deklariert ist. Also besser das Array mit Index 0 beginnen lassen, auch wenn der Eintrag im SPS-Programm vielleicht nicht verwendet wird.

PS: ach, habe den Beitrag #11 von @Botimperator gerade erst gesehen.
 
Hallo,

ich würde mit einem UDT arbeiten:
Array[0..53] of UDT

Alternativ:
Array[0..53, 0..1] of DInt

Vergiss nicht den Index vom HMI auf Plausibilität abzufragen.

Gruß

Oder alternativ der Vollständigkeit halber:

Array[0..53] of Struct
und im ersten Element das Struct definieren.

Ich mache das aber auch so wie @DCDCDC im Beitrag #6

-chris
 
Validate axis in position
Code:
IF #ioIgus.Out.Referenced THEN
    FOR #tempValidateAxisPos := 1 TO "AXIS_POS_MAX" BY 1 DO
        #ioPositionData[#tempValidateAxisPos].InPosition := (#ioIgus.PositionData.ActualPosition <= #ioPositionData[#tempValidateAxisPos].Position + #iPositionTolerance) AND
        (#ioIgus.PositionData.ActualPosition >= #ioPositionData[#tempValidateAxisPos].Position - #iPositionTolerance);
        IF #ioPositionData[#tempValidateAxisPos].InPosition THEN
            #tempInPosition := 1;
            EXIT;
        END_IF;
    END_FOR;
END_IF;

Verhindern dass Positionen / Geschwindigkeiten eingetragen werden, die über die Limits der Hardware gehen:
Screenshot 2024-07-04 164424.png

Selection target position
Code:
IF #ioMode.Mode.SetupActive AND #ioIgus.In.OperationMode = #constMODE_POS THEN
    #statRTRIG_PositionSelection(CLK := #ioIgus.Hmi.PositionSelection <> #tempPositionSelectionOld,
                             Q => #statRTRIG_PositionSelection.Q);
    IF #statRTRIG_PositionSelection.Q THEN
        #ioIgus.PositionData.TargetAccDcc := #ioPositionData[#ioIgus.Hmi.PositionSelection].AccDcc;
        #ioIgus.PositionData.TargetPosition := #ioPositionData[#ioIgus.Hmi.PositionSelection].Position;
        #ioIgus.PositionData.TargetVelocity := #ioPositionData[#ioIgus.Hmi.PositionSelection].Velocity;
        #ioIgus.Hmi.Interlock := #ioPositionData[#ioIgus.Hmi.PositionSelection].Interlock;
        #tempPositionSelectionOld := #ioIgus.Hmi.PositionSelection;
    END_IF;
END_IF;

IF (#ioMode.Mode.AutoActive OR #ioMode.Mode.HomePosActive) AND #ioIgus.In.OperationMode = #constMODE_POS THEN
    #ioIgus.PositionData.TargetAccDcc := #ioPositionData[#ioIgus.Control.Position].AccDcc;
    #ioIgus.PositionData.TargetPosition := #ioPositionData[#ioIgus.Control.Position].Position;
    #ioIgus.PositionData.TargetVelocity := #ioPositionData[#ioIgus.Control.Position].Velocity;
    #ioIgus.Control.Interlock := #ioPositionData[#ioIgus.Control.Position].Interlock;
    #ioIgus.Hmi.Override := 100;
END_IF;

Als Beispiel..
 
Zurück
Oben