Anfängerfragen zu TwinCAT 3.1 und ST

bone666

Level-1
Beiträge
72
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Tag Zusammen,

ich habe angefangen mich für eine Bachelorarbeit in TwinCAT und ST einzuarbeiten.
Nun habe ich einige Fragen und versuche diese strukturiert und möglichst verständlich zu erklären.

Folgende Deklaration und Funktion habe ich bis jetzt im PLC_PRG, dies ist mir jedoch zu unübersichtlich.
Gibt es eine Möglichkeit das alles in einen FB zu schreiben? Ich weiß nur nicht wie ich das dann mit den VAR_INPUT/OUTPUT machen soll.

Meine Struktur st_Sicherungsabgaenge, dazu habe ich noch eine Frage. Habe das by_Zustand:BYTE; irgendwo im Netz gefunden und frage mich nun wie das Byte z.b. Wartung oder so darstellen/ausgeben soll.
Code:
TYPE st_Sicherungsabgaenge :
STRUCT
    by_Zustand:      BYTE;    (*EIN,AUS,Wartung,Fehler...*)
    i_Temperatur:    INT;
    x_Ausloesung:    BOOL;    (*Ja := TRUE, Nein := FALSE*)
END_STRUCT
END_TYPE

Meine Variablendeklaration bis jetzt im PLC_PRG
Code:
VAR
arr_Sicherungen:        ARRAY[1..3] OF st_Sicherungsabgaenge;
    i_PointerAufArray:        INT:=1;
    i_SpeicherTemperatur:    INT;
    x_Error:                 BOOL;
    i_UntereGrenzePointer:    INT:=1;
    i_ObereGrenzePointer:    INT:=3;
    st_Ausloesung:            ARRAY[1..3] OF STRING;
    i,j,a,b:                INT;
    arr_Meldungen:            ARRAY[1..10] OF STRING;
    arr_Fehler:                ARRAY[1..10] OF STRING;
    arr_Ereignisse:            ARRAY[1..10] OF STRING;
END_VAR

Und meine "Funktionsaufrufe" oder wie man es auch nennen möchte, ebenfalls im PLC_PRG.
Dazu eine Frage: Kann ich so etwas wie IF(arr_Sicherungen.x_Ausloesung...... THEN st_Ausloesung:='Sicherung ausgelöst'; schreiben, also alle Fälle auf einmal abarbeiten?
Code:
IF (arr_Sicherungen[1].x_Ausloesung = TRUE) THEN    
st_Ausloesung[1]:='Sicherung ausgelöst!';            
END_IF;                                                

IF (arr_Sicherungen[2].x_Ausloesung = TRUE) THEN    
st_Ausloesung[2]:='Sicherung ausgelöst!';
END_IF;

IF (arr_Sicherungen[3].x_Ausloesung = TRUE) THEN
st_Ausloesung[3]:='Sicherung ausgelöst!';
END_IF;

Hatte eventuell gedacht, die ganzen Deklarationen in ein STRUCT zuverpacken, weiß aber dann nicht wie ich das in einen FB einbinde, sodass es das selbe tut wie bis jetzt.

Dann habe ich noch einen FB, welcher zwar funktioniert, vielleicht jedoch noch optimiert werden kann.

Code:
FUNCTION_BLOCK FB_Leistungsfaktor
VAR_INPUT
    rl_Wirkleistung:    REAL;
    rl_Scheinleistung:    REAL;
END_VAR
VAR_OUTPUT
    rl_Leistungsfaktor:    REAL;
    x_ERROR:            BOOL;
END_VAR
VAR
END_VAR
------------------------------------------------
IF (rl_Scheinleistung <> 0) THEN                            (*Kontrolle ob durch 0 dividiert werden soll*)
rl_Leistungsfaktor:=(rl_Wirkleistung / rl_Scheinleistung);    (*Wenn rl_Blindleistung ungleich 0 ist, wird die Division*)
x_ERROR:=FALSE;                                                (*durch geführt, sonst wird zur ELSE-Anweisung gesprungen*)
ELSE
x_ERROR:=TRUE;                                                (*Bei Division durch 0 wird x_ERROR auf FALSE gestellt*)
END_IF;
RETURN;


MfG

Bone
 
Da jeder Sicherungsabgang einen st_Ausloesung braucht, würde ich den mit in das Struct packen. Die Structs kannst Du dann mit einer Schleife bearbeiten.
Code:
VAR
       Index:BYTE;
END_VAR

FOR Index:= i_UntereGrenzePointer TO i_ObereGrenzePointer DO
       IF arr_Sicherungen[Index].x_Ausloesung THEN 
      arr_Sicherungen[Index].st_Ausloesung:='Sicherung ausgelöst!';             
   END_IF;
END_FOR

In einem weiteren Schritt könntest Du statt des Structs einen FB mit den gleichen Variablen deklarieren, im Hauptprogramm dann ein Array of FB_Sicherungsabgang anlegen und diese FBs in einer Schleife aufrufen.
Code:
FUNCTION_BLOCK fb_Sicherungsabgang
VAR
   by_Zustand:      BYTE;    (*EIN,AUS,Wartung,Fehler...*)     
   i_Temperatur:    INT;
   x_Ausloesung:    BOOL;    (*Ja := TRUE, Nein := FALSE*) 
   st_Ausloesung:String;
END_VAR

 IF x_Ausloesung THEN 
    st_Ausloesung:='Sicherung ausgelöst!';             
END_IF;


(* Im Hauptprogramm *)
VAR
   arr_Sicherungsabgaenge:ARRAY[1..3] OF fb_Sicherungsabgang;
END_VAR

FOR Index:= i_UntereGrenzePointer TO i_ObereGrenzePointer DO
    arr_Sicherungsabgaenge[Index](); 
END_FOR
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@ StructuredTrash: Erstmal Danke für deine Antwort.
Ich verstehe was du meinst, jedoch hapert es an der Umsetzung.
Bei der Variante mit der erweiterten STRUCT, meckert TC wenn ich .x_Ausloesung forcen will um das zu testen, dass ich diese Variable nicht forcen kann. Blicke nicht ganz durch -.-

Variante mit FB statt Struct:
Wenn ich die Variablen im FB in VAR/END_VAR deklariere kann im im Hauptprogramm ja nichts mit dem FB anstellen weil der ja Inputvariablen will oder bringe ich da was durcheinander?

Kurz gesagt, ich verstehe den Ansatz, bekomme es jedoch nicht umgesetzt, sodass es funktioniert.
 
Hallo, ich habe noch eine Frage. Wie schaffe ich es, dass ein String in z.B. zwei Zeilen ausgegeben wird?
Also statt
'Alles in einer Zeile'
etwa so
'Alles in
einer Zeile'
Habe etwas von $R oder $N gelesen, jedoch funktioniert weder das Eine noch das Andere. Auch beides in kombination bringt nichts.
 
@StructuredTrash
Irgendwie wird meine Antwort auf deinen Betrag nicht angezeigt, also noch einmal.

Ich verstehe den Sinn hinter deinen Vorschlägen, jedoch hapert es an der Umsetzung.
Ein FB braucht im Programm doch INPUTvariablen oder nicht? Also müsste ich die ja im FB in VAR_INPUT deklarieren und nicht in VAR oder?

Bei der STRUCT Variante, kann ich irgendwie nicht .x_Ausloesung forcen beim testen, sodass die IF-Schleife nicht wirklich funktioniert.
Keine Ahnung ob ich alles richtig eingegeben habe. Eigentlich musste ich ja nur deins kopieren oder nicht und ggf. anders bennen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe es gerade mal ausprobiert mit $R, funktioniert tatsächlich nicht. In TC2 ging es noch. Die TC3-Visu ist wohl noch nicht ganz fehlerfrei, z. B. kann man bei der Eingabe eines negativen Wertes im Numpad das Minuszeichen erst nach den Ziffern eingeben. Aber wen stören solche Kleinigkeiten angesichts der kolossalen neuen Features? :ROFLMAO:
 
Noch zum FB: Wenn der keine INPUT-Variablen deklariert, erwartet er auch keine vom PRG. Allerdings hast Du vom PRG aus keinen Zugriff auf die lokalen FB-Var (In TwinCat/CoDeSys zwar doch, aber das war ursprünglich ein Bug, der mit der Zeit zu einem Feature geworden ist, die Anwendung ist in meinen Augen Sünde).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich meine folgende stelle im Programm, das war doch soweit dein Vorschlag oder habe ich etwas falsch umgesetzt?

force_fehler.jpg

Ich bin etwas verwirrt, bleibe nun erstmal bei meinem Eingangsprodukt.

Habe nun jedoch noch eine Frage bzgl. einer Visualisierung. Ich habe ein Rechteck gezogen im Textfeld steht %s und die Text Variable zugeordnet. Wenn ich das Programm auf Run stelle kann ich im Variablenbeobachtungskasten sehen, dass die Variable den Text als String hat, welchen sie haben soll. Jedoch steht im Rechteck nun einfach 101 und nicht der String. Bei anderen Elementen funktioniert es ohne Probleme nur bei diesem Rechteck nicht.
visu_fehler.jpg
 
Hi,
zum Force Problem:
Im Beispiel von StructuredTrash wird die Variable im Deklarationsteil geforced , und das gezielt im Index 1 des Arrays.
Du hingegen versucht im Quellcode direkt in der For Schleife zu forcen. Welchen Index soll TC nehmen?
Denke dass das Problem ist...
 
Hi TwinKater,

das könnte es sein, jedoch kann ich in TwinCAT3 nicht im Deklaratoinsteil forcen bzw. muss man dafür noch was einstellen/ändern? Nur im Programmteil selber kann ich forcen.
forcen_deklarationsteil.jpg
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
In TC3 musst Du den gewünschten Wert in der Spalte rechts neben den aktuellen Werten eintragen und die Forcefunktion dann im PLC-Menüfenster auswählen.
Bei der Stringausgabe schreibe mal im Eigenschaftenfenster ".st_Uebertemp", ".st_Uebertemp[1]" ist nur das erste Zeichen des Strings als Byte.
 
Danke Trash, habe bis jetzt immer im Programmtext selber die Werte geforcet. Und das mit [] statt [1] hat es auch gebracht.

Jetzt steht erstmal nur noch die Sache mit dem String "teilen" im Raum.
Also statt 'Das ist ein String' möchte ich 'Das ist
ein String'
haben, also einen Zeilensprung. Mit &R oder &N klappt es nicht oder ich habe noch nicht die richtige Kombination gefunden -.-
 
Zurück
Oben