Step 7 Auf UDT-Elemente in Schleife zugreifen

Zuviel Werbung?
-> Hier kostenlos registrieren
ich möchte die Grundfunktion in verschiedenen Maschinen einsetzen, aber anpassen.
Ich habe aber immer ganz unterschiedlich benannte Zähler, daher das Beispiel mit dem Zoo.
Im restlichen Programm das je nach Maschine sehr unterschiedlich ist möchte ich mit den Namen arbeiten.
Da ich jetzt aber in meinem Baustein alle Zähler durchgehen will ohne sie einzeln mit Name aufzurufen, also einzeln zu schreiben habe ich dafür die einfachste Lösung gesucht.
Wenn du es in einem FB kapselst dann könntest du vom Hauptprogramm her den FB ja auch dazu auffordern, dir das gewünschte zu liefern. Du kannst den FB mit gleicher Instanz ja beliebig oft im Programm aufrufen. Über die Baustein-Schnittstelle legst du dann fest was der jeweilige Aufruf dann tun soll ...
 
... Wenn ich jetzt ein UDT-Array und Konstanten verwende muss ich im restlichen Programm immer noch ein bisschen aufpassen, aber das bleibt überschaubar.

Das mit den globalen Konstanten hatte ich dir ja schon in #8 vorgeschlagen. Ich möchte noch ergänzen, dass ich meine Datensätze auch in Arrays of UDT ablege, wie viele andere Kollegen natürlich auch. Anfangs hatte ich auch den Wunsch nach den globalen symbolischen Konstanten, was ich aber schnell wieder verworfen habe. Stattdesen schreibe ich meine Bezeichnungen in die Kommentare der Array-Elemente im DB. Diese Kommentare bleiben auch bei Änderungen erhalten. Navigieren kann man sehr nervenschonend über die Querverweise <F11> direkt aus dem DB heraus. Wenn ich KATER[36] suche, öffne ich ganz einfach den DB, gehe auf das entsprechende Element und drücke <F11>. Der Rest der Orientierung ist meist mit Netzwerküberschriften kurz und präzise erledigt.

Ein weiterer Versuch war, FBs der Anlagenteile über Aktualparameter (INOUT, UDT) von außen mit den ARRAY-Elementen zu versorgen und intern mit den Symbolen dieser Bausteinparameter zu arbeiten. Das habe ich an wenigen Projekten so praktiziert. Für mich hat es sich allerdings nicht bewährt. Zum Beispiel findet dann das oben genannte Navigieren aus dem DB heraus am Aktualparameter sein Ende. An dieser Stelle muss man dann wieder umdenken und im FB mit dem Symbol weitersuchen, was einfach nur nervt. Aber vieleicht wäre das aber noch eine Lösung für dich.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja, die Hunde, Katzen usw. sind ja Bestandtteil des UDT, die Zeitpunkte sind des Array... Wenn Du jetzt noch Elefanten hinzufügen musst, kannst das ja im UDT hinzufügen, ohne das sich am restlichen Programm was ändert, aber natürlich mit Aktualdatenverlust und nicht im laufenden Betrieb...
Nein genau das eben nicht, der Elefant wäre ein neues Array-Element.
Die Zeitpunkte sind im UDT.
 
Hier mal ein Ansatz ZaehlerUdt = dein UDT01



CounterAddition addiert immer eine Counter UDT auf eine Andere. Es wird davon ausgeganegen, das in der Zähler UDT nur DINT Werte liegen und wenn die UDT von Projekt zu Projekt angepasst wird muss "CounterAddition".counterMax angepasst werden (Der Compiler wird meckern, wenn es nicht stimmt.

1736357195818.png

FB:
FUNCTION_BLOCK "CounterAddition"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT DB_SPECIFIC
CounterX { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "ZaehlerUdt";
nextCounter { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} AT CounterX : Array[0..#counterMax] of UDInt;
END_VAR

VAR_IN_OUT
CounterGes : "ZaehlerUdt";
END_VAR

VAR DB_SPECIFIC
CounterGesTemp { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "ZaehlerUdt";
CounterGesArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} AT CounterGesTemp : Array[0..#counterMax] of UDInt;
END_VAR

VAR_TEMP
i : Int;
END_VAR

VAR CONSTANT
counterMax : Int := 5;
END_VAR

BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;


#CounterGes := #CounterGesTemp; // Summenzähler zurückgeben

END_FUNCTION_BLOCK



BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;


#CounterGes := #CounterGesTemp; // Summenzähler zurückgeben


END_FUNCTION_BLOCK



BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;
END_FUNCTION_BLOCK


BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;
END_FUNCTION_BLOCK


Viel Spaß beim Testen
Thomas
 

Anhänge

  • 1736356178565.png
    1736356178565.png
    135,1 KB · Aufrufe: 5
  • TestCall.scl
    TestCall.scl
    2,7 KB · Aufrufe: 3
Bitte CodeTags benutzen
(Die Einrückungen mit dem Handy zu machen war mir jetzt zu aufwendig)

Code:
FUNCTION_BLOCK "CounterAddition"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT DB_SPECIFIC
CounterX { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "ZaehlerUdt";
nextCounter { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} AT CounterX : Array[0..#counterMax] of UDInt;
END_VAR

VAR_IN_OUT
CounterGes : "ZaehlerUdt";
END_VAR

VAR DB_SPECIFIC
CounterGesTemp { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "ZaehlerUdt";
CounterGesArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} AT CounterGesTemp : Array[0..#counterMax] of UDInt;
END_VAR

VAR_TEMP
i : Int;
END_VAR

VAR CONSTANT
counterMax : Int := 5;
END_VAR

BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;


#CounterGes := #CounterGesTemp; // Summenzähler zurückgeben

END_FUNCTION_BLOCK



BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;


#CounterGes := #CounterGesTemp; // Summenzähler zurückgeben


END_FUNCTION_BLOCK



BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;
END_FUNCTION_BLOCK


BEGIN
// Addieren eines Counterblocks zu einem Anderen

#CounterGesTemp := #CounterGes; // Daten in Lokadatan laden

FOR #i := 0 TO #counterMax DO
#CounterGesArray[#i] := #CounterGesArray[#i] + #nextCounter[#i];
END_FOR;
END_FUNCTION_BLOCK
 
Zurück
Oben