TIA "Reflection" in der SPS?

Alpini

Level-1
Beiträge
21
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich bin sonst eher im Bereich der Hochsprachenprogrammierung (.net) unterwegs und muss nur ab und zu mal etwas an unserer SPS ändern. In .net gibt es die Möglichkeit "reflection" zu nutzen (per "using reflection;"). Grob gesagt kann man sich damit z.B. zur Laufzeit einen Variablennamen-String zusammenbasteln und über diesen dann auch z.B. den Wert der Variable abfragen oder setzen. Normalerweise sind (ohne Reflection) Variablennamen ja zur Laufzeit fix. Ein C# Beispiel wäre:

Code:
string MyVarName = "blnSteuerung";
FieldInfo FI = ClassXYZ.GetType().GetField(MyVarName);

Im Beispiel wäre "MyVarName" mein zur Laufzeit "gebastelter" Variablenname und über die "FI" Klasse könnte ich den Wert von "blnSteuerung" abrufen/ändern.

Jetzt die entscheidende Frage: geht sowas auch in der SPS per AWL? Also könnte man irgendwie dynamisch z.B. Ausgänge ansteuern, die vorher nicht explizit im Programm benannt sind?

Ein Anwendungsbeispiel: Ich schreibe vom PC mit der Bibliothek "s7netplus" eine Ausgangsbytenummer (z.B. 30) in ein Merkerwort und eine Ausgangsbitnummer (z.B. 5) in ein zweites Merkerwort und die SPS baut diese beiden zu einem "A30.5" zusammen.

Viele Grüße, Stefan
 
Zuletzt bearbeitet:
Hast du eine TIA oder classic Steuerung?

Für die S7 1200/1500 gibt es in SCL den peek und poke Befehl. Damit wäre genau das möglich

EDIT: sehe gerade du willst das mit AWL lösen... Da hab ich leider keine Lösung
 
Eine echte Refektion, wie du es von der .Net-Programmierung her kennst, ist auf der SPS-Ebene so nicht möglich.
Du kannst natürlich jede Variable symbolisch (mit deren Namen) ansprechen - ich vermute aber, dass es das nicht ist was du willst ...
 
Ich hatte mir bei der S5 mal so einen Baustein geschrieben (um beliebige Bitsignale auf eine Prüflampe zu legen).
Für S7 dann angepasst und für TIA mit PEEK_BOOL nochmals angepasst.

Hier die S7 (Classic / AWL) Version, funktioniert auch bei 1500:

1677585088386.png
Code:
// FC STAT.ANZ   18.10.1999, P. Wahlen

// Der Baustein bietet die Möglichkeit, beliebige Ein-,Aus-gänge und Merker
// auf einen Ausgangsformaloperanden zu legen. Man kann damit z.B.: einen
// Merker auf eine Prüflampe legen.
//
// ACHTUNG!!!...
//-------------
// Es ist günstiger die ADF-Überwachung auszuschalten,bzw.im entsprechenden
// Fehler-OB den Operand auf einen Merker zu setzen.
// Die elegantere Lösung ist die Grenzwerte der E,A und M im FC zu überwachen.

      CLR                        // HM vorbereiten
      =     #HM_E
      =     #HM_A
      =     #HM_M

      L     #Bit_Nr              // - Bit-Nr ok ?
      L     0
      <I
      SPB   BitK                 // - Sprung, bei Bit-Nr < 0
      L     #Bit_Nr
      L     7
      >I
      SPB   BitK                 // - Sprung, bei Bit-Nr > 7
      SPA   maxE                 // - Grenzwert setzen überspr.
BitK: T     #Bit_Nr              // - Grenzwert (0, 7) nach Bit-Nr

//    ---------- Byteadresse begrenzen
maxE: L     #Operand             //   Operand E (1) erhalten
      L     1
      <>I
      SPB   maxA
      =     #HM_E
      L     #maxE
      SPA   maxG
maxA: L     #Operand             //   Operand A (0) erhalten?
      L     0
      <>I
      SPB   maxM
      =     #HM_A
      L     #maxA
      SPA   maxG
maxM: L     2                    //   kein Ein-, Ausgang; dann
      T     #Operand             //   M (2) nach Operand
      SET
      =     #HM_M
      L     #maxM
maxG: T     #maxG                // Bytegrenzwert setzen

      L     #Byte_Nr             // - Byte-Nr ok ?
      L     0
      <I
      SPB   BytK                 // - Sprung, bei Byte-Nr < 0
      L     #Byte_Nr
      L     #maxG
      >I
      SPB   BytK                 // - Sprung, bei Byte-Nr > maxG
      SPA   Komb                 // - Grenzwert setzen überspr.
BytK: T     #Byte_Nr             // - Grenzwert (0, maxG) nach Byte-Nr

//    ---------- Byte + Bit kombinieren
Komb: L     #Byte_Nr
      SLD   3                    //   auf richtige Pos. schieben
      L     #Bit_Nr
      OD                         //   verknüpfen
      T     #Zeiger              //   = Byte + Bit
//    ---------- Eingang
      UN    #HM_E                //   Operand E erhalten
      SPB   Ausg                 //   sonst Sprung
      U E [ #Zeiger]
      SPA   Anz
//    ---------- Ausgang
Ausg: UN    #HM_A                //   Operand A erhalten?
      SPB   Merk
      U A [ #Zeiger]
      SPA   Anz
//    ---------- Merker
Merk: U M [ #Zeiger]             //   kein Ein-, Ausgang; dann Operand M

//    ---------- zuweisen
Anz:  =     #Ausgang             //   nach Ausgang übertragen
 
Hallo,

Danke an alle und sorry für die späte Rückmeldung, ich war leider durch unangenehmere Dinge als SPS Programmierung verhindert :).

Ich nutze TIA V.17, die Steuerung ist aber noch eine S7-315, wodurch PEEK/POKE wegfällt (trotzdem interessant zu wissen, was in den neueren Modellen geht).

Auch wenn ich Peters Baustein noch nicht zu 100% verstehe (da muss ich noch etwas AWL lernen), denke ich, dass er genau das macht, was ich benötige - nur umgekehrt. Ein großes Danke dafür! Bei mir müsste sein Output "Ausgang" nicht als Output nach außen geführt sein, sondern durch den Baustein direkt gesetzt werden , sein InOut Parameter "Operand" wäre bei mir immer ein Ausgang und könnte daher weggelassen werden. Und die InOut Parameter "Byte_Nr", "Bit_Nr" würden immer einen Ausgang bezeichnen. Einen In-Parameter "Ausganswert" vom Typ Bool müsste ich noch hinzufügen mit dem Wert, der dem Ausgang zugewiesen werden soll.

Ich werde nächste Woche mal probieren, ob ich den Baustein umgebaut bekomme - das wäre super. Ziel wäre eine Wartungssteuerung in einem PC-Programm auf einem Notebook, mit deren Hilfe man beliebige Ausgänge in der SPS ein- und ausschalten kann noch etwas auszubauen. Damit könnte man dann z.B. Zahnriemenführungen, die sonst im regulären Betrieb nur ca. eine Sekunde lang laufen, für längere Zeit aktivieren und nach einem Riemenwechsel die Spann- und Umlenkrollen wieder so einstellen, dass der Riemen in der Mitte läuft. Und man würde sich so eine Menge Programmierarbeit in der SPS und viele Schaltschranktaster ersparen und könnte die gewünschten Ausgänge auch direkt an Ort und Stelle ein und ausschalten, ohne immer zum Schaltschrank rennen zu müssen. Aktuell habe ich für ausgewählte Ausgänge schon so eine Steuerung, aber da wird von PC-Seite in der SPS jeweils ein Merker gesetzt/rückgesetzt, der dann in der SPS einem ganz bestimmten Ausgang zugewiesen wird. Das ist wenig universell und bei ein paar hundert Ausgängen keine schöne Methode, ein direktes Ansprechen wäre da absolut top.

Viele Grüße, Stefan
 
Zuletzt bearbeitet:
beliebige Ausgänge in der SPS ein- und ausschalten (...)
man würde sich so eine Menge Programmierarbeit in der SPS und viele Schaltschranktaster ersparen
Programmierarbeit sparen :ROFLMAO:

Du weißt, daß man bei SPS im RUN nur Ausgänge steuern kann, denen vom Programm nichts zugewiesen wird? Du müsstest viel zusätzlichen und umständlichen Code in der SPS programmieren, damit so ein Steuern überhaupt funktioniert und müsstest ständig Angst haben, daß Du Deine Anlage zu Schrott kaputtsteuerst. Du kannst Deine Hochsprachen-Erfahrung nicht mit SPS-Programmierung vergleichen. Informiere Dich mal über die zyklische Arbeitsweise von SPS.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du weißt, daß man bei SPS im RUN nur Ausgänge steuern kann, denen vom Programm nichts zugewiesen wird? Du müsstest viel zusätzlichen und umständlichen Code in der SPS programmieren, damit so ein Steuern überhaupt funktioniert und müsstest ständig Angst haben, daß Du Deine Anlage zu Schrott kaputtsteuerst. Du kannst Deine Hochsprachen-Erfahrung nicht mit SPS-Programmierung vergleichen. Informiere Dich mal über die zyklische Arbeitsweise von SPS.

Harald

Es gibt da ein (unsauberen) Trick um das ohne viel Aufwand zu schaffen:
Den Wunsch-Ausgangs-Ansteuerbaustein als letztes im OB Main aufrufen. Dann werfen vorherige Ansteuerungen überschrieben.
Funktioniert allerdings nur, wenn keine Zeit Ob's verwendet werden, bzw., in den Zeit OB's keine von diesen Ausgängen angesteuert werden.

Sinnvoll wäre es, bei manueller Ausgangsansteuerung:
  • Meldung "Ausgang manuell gesteuert"
  • Verhinderung der Automatik
 
Zuletzt bearbeitet:
zur Info:

Ich hatte den FC (bei S5 FB) nur geschrieben und verwendet, um von einem Terminal beliebige Bitsignale auf eine Prüflampe / LED zu legen. Diese Lampen waren an mehren Stellen an den Anlagen verteilt waren bei Fehlersuchen hilfreich, besonders bei Kabelbruch am Sensor, weil die Prüf-LED's mit Zyklusgeschwindigkeit angesteuert wurden und selbst kurzzeitiges Flacken bei wackeln am Sensorkabel schnell festgestellt wurde.
 
Zuletzt bearbeitet:
Du weißt, daß man bei SPS im RUN nur Ausgänge steuern kann, denen vom Programm nichts zugewiesen wird? Du müsstest viel zusätzlichen und umständlichen Code in der SPS programmieren, damit so ein Steuern überhaupt funktioniert und müsstest ständig Angst haben, daß Du Deine Anlage zu Schrott kaputtsteuerst. Du kannst Deine Hochsprachen-Erfahrung nicht mit SPS-Programmierung vergleichen. Informiere Dich mal über die zyklische Arbeitsweise von SPS.

Hallo Harald,

prinzipiell hast du Recht, aber ich kann ja bereits jetzt schon Ausgänge steuern, die sehr wohl im SPS-Programm zugewiesen werden. Ich mache das genau so wie Peter es beschreibt: Ein Wartungs-FB, der im OB1 im letzten Netzwerk aufgerufen wird, überschreibt die zuvor durch das SPS-Programm gesetzten Ausgangszustände. Die Ausgänge werden da allerdings indirekt über einen zugehörigen Merker gesetzt. In dem Wartungs-FB wird ein von der PC-Seite geschriebener Merker ausgewertet und bei "true" per SET auf den Ausgang geschrieben. Bei fallender Flanke des Merkers wird der Ausgang (einmalig) per RESET ausgeschalten. Ab dann hat der Ausgang am Ende des Zyklus wieder den Wert, den das SPS-Programm ihm gegeben hat. Bei nicht gesetztem Merker wird der Ausgang im Wartungs-FB also nicht mehr verändert. Das funktioniert zuverlässig und der zugehörige Programmcode ist sehr überschaubar, man muss aber halt für jeden zu steuernden Ausgang einzeln neu schreiben. Aufpassen muss man bei Ausgängen, die im Zusammenhang stehen (z.B. Wendeschützschaltungen) - dort muss man beim Setzen gleichzeitig den zweiten Ausgang rücksetzen.

Code:
//Ausgang Start
      U     "AusgangsmerkerA10.0"
      S     A10.1
      
//Ausgang Stopp
      U     "AusgangsmerkerA10.0"
      FN    "FlankenmerkerMXX.X"
      R     A10.1

Und ja, ein direktes Schreiben eines Ausganges von PC-Seite aus funktioniert nur bei Ausgängen, die sonst nicht verwendet werden - das macht also wenig Sinn.

Ich bin mir auch im klaren darüber, dass das nicht super sauber ist, das würde auch anders direkt in den jeweiligen Netzwerken gehen. Aber so ist es vielleicht sogar am Fehler-unanfälligsten, sofern man den Wartungs-FB-Aufruf mit einem dicken Kommentar versieht, dass er immer der letzte im OB1 bleiben muss.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
//Ausgang Start
      U     "AusgangsmerkerA10.0"
      S     A10.1
     
//Ausgang Stopp
      U     "AusgangsmerkerA10.0"
      FN    "FlankenmerkerMXX.X"
      R     A10.1
den Code kannst du dir sparen, wenn du dir einen Freien Ausgang (wo nix angeschlossen ist) (bzw. einen freien Merker) definierst.
auf den legst du dann die Parameter deines Ansteuer-Überbrückungs-Bausteines.

z.B. Freier Ausgang: A39.7, Byte 37, Bit 7
 
Richtig faule Programmierer machen sich z.B. einen Merker-Bereich für die Programmzuweisungen (z.B. M100.0 - M149.7) und einen Bereich für die manuellen Übersteuerungen oder "Handbetrieb" (z.B. M200.0 - M249.7) und ver-Odern die Bereiche am Ende Doppelwordweise und weisen dann an die Ausgänge zu (z.B. A0.0 - A49.7) Ausschalten von im Programm eingeschalteten Ausgängen gibt es da nicht, weil das macht dann doch noch ein bisschen mehr Arbeit...

Harald
 
Hallo,

es ist zwar nicht in der Siemenswelt (Step5/Step7 bzw. TIA) aber ich würde dies trotzdem in Richtung Fragesteller als Offtopic-Exkurs und zusätzlicher Information hinzufügen. (Darf aber auch gerne, falls nicht gewünscht wieder entfernt werden)

Dein beschriebenes Szenario in Richtung "reflection" kann in der CODESYS - Welt genauso auch angewendet werden. Ich nutze diese Funktion z.B. für das Errorhandling in Kombination mit einem Observer-Pattern, dies ermöglicht mir, mit geringem Aufwand, eine detaillierte Pfadangabe zum aufgetretenen Fehler zu bekommen.

Voraussetzung ist hierbei:
* In jedem benötigten FB muss das Attribut "reflection" hinzugefügt werden
* Zusätzlich müssen beide Attribute "instance-path" und "noinit" an die jeweilige temporäre Variable hinzugefügt werden .
1678104056801.png

Das ganze sieht dann im Online wie folgt aus:
Bausteinhierarchie: PLC_PRG -> FB_Bridge -> FB_ShowReflection
Die Methode GetName von Baustein FB_Bridge dient in diesem Beispiel nur zum durchreichen der Variable "_sObjectName".

1678103927468.png
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Richtig faule Programmierer machen sich z.B. einen Merker-Bereich für die Programmzuweisungen (z.B. M100.0 - M149.7) und einen Bereich für die manuellen Übersteuerungen oder "Handbetrieb" (z.B. M200.0 - M249.7) und ver-Odern die Bereiche am Ende Doppelwordweise und weisen dann an die Ausgänge zu (z.B. A0.0 - A49.7) Ausschalten von im Programm eingeschalteten Ausgängen gibt es da nicht, weil das macht dann doch noch ein bisschen mehr Arbeit...

Harald
Das sind aber schon die ganz alten Tricks aus der Programmierkiste, da gab's ja auch den Spruch: "Faul darf man sein, aber nicht dumm."
Deshalb die Erweiterung: Noch ein Wort (alles 1er) nach der VerOderung VerUnden, dann geht auch das Ausschalten (mit "0" an der gewünschten Stelle..
 
Hallo,

ich melde mich nochmal zurück um Danke zu sagen :)

Peters Lösung mit dem zusammengebauten Zeiger funktioniert für meine Zwecke einwandfrei und tut genau das, was ich wollte! Ich habe auch einen kleinen FB daraus gemacht:

Variablen.png

Code:
//    ---------- Byte + Bit kombinieren
      L     #ByteNr              //Byte-Nummer laden
      SLD   3                    //Byte um 3 Bit nach links schieben, damit Platz für das Bit bleibt, welches später per OD verknüpft wird
      L     #BitNr               //Bit-Nummer laden
      OD                         //Byte und Bit per OR verknüpfen
      T     #Pointer             //Byte + Bit in #Pointer übertragen

//    ---------- Pointer aus letztem Zyklus mit aktuellem Pointer vergleichen und bei Unterschied den letzten Ausgang deaktivieren
      L     #LastPointer
      T     #LastPointerTmp      //LastPointer inLastPointerTmp kopieren, wegen indirekter Adressierung

      L     #Pointer
      L     #LastPointer
      <>I                        //Zeiger vergleichen
      R A [ #LastPointerTmp]     //wenn ungleich, LastPointerTmp rücksetzen

//    ---------- Ausgang aktivieren, wenn #aktivieren == true
      U     #Aktivieren          //true laden
      S A [ #Pointer]            //Zeigervariable auf True setzen

//    ---------- Ausgang bei fallender Flanke von #Aktivieren deaktivieren
      U     #Aktivieren
      FN    #FlankenMerker
      R A [ #Pointer]

//    ---------- aktuellen Pointer in LastPointer transferieren
      L     #Pointer
      T     #LastPointer

Die Variablen "ByteNr", "BitNr" und "Aktivieren" werden von PC-Seite aus direkt in den zum FB gehörenden DB geschrieben:

Code:
//S7Netplus Ausgang aktivieren:
PLC.Write("DB200.DBD0", ByteNr);    //ByteNr - DWord
PLC.Write("DB200.DBD4", BitNr);     //BitNr - DWord
PLC.Write("DB200.DBX8.0", true);    //Aktivieren - Merker

//S7Netplus Ausgang deaktivieren:
PLC.Write("DB200.DBX8.0", false);    //Aktivieren - Merker

Im Programm sieht es dann so aus:

Programm.png

Wird der Haken oben gesetzt, aktiviert sich der Ausgang, wird der Haken wieder entfernt oder ein anderer Ausgang in der ComboBox oben gewählt, deaktiviert das den zuvor gewählten Ausgang wieder. Etwas Sicherheit muss man noch drumherum programmieren, z.B. falls das Fenster geschlossen wird, während ein Ausgang aktiviert ist.

Viele Grüße,

Stefan
 
Zuletzt bearbeitet:
Sicher praktisch es werden aber dann alle Sicherheitsfunktionen ausgehebelt.
Ob das so zulässig ist?????
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich denke das muss man immer im Einzelfall beurteilen, bei uns wird die Sicherheit nicht dadurch ausgehebelt, da die sicherheitsrelevanten Sachen in Hardwareform und nicht durch die SPS abgeschalten werden. Zum Großteil geht es bei uns um Rollenbahnen, Zahnriemenförderer, etc. im Logistikbereich, auf welchen langsam leichte Behälter herumfahren und kaum Verletzungsgefahr besteht und welche so gebaut sind, dass Menschen während dem Betrieb daran arbeiten dürfen.

Ausgänge mit Verletzungsgefahr sollte man so nicht steuerbar machen oder zumindest die Sicherheit zusätzlich in Hardwareform noch "vorschalten". Beides ist ja vereinbar. Bisher hatten wir so eine Wartungssteuerung in Form von Tastern an verschiedenen Schaltschränken, was eher gefährlicher als die neue Lösung ist, da man die gesteuerten Anlagenteile von den Schaltschränken aus teils nicht einsehen kann und nur durch Zurufen arbeiten konnte.

Den Zugang zur PC-Wartungssteuerung kann man durch Kennworte, VLAN's etc. genauso gut oder sogar besser absichern als am Schaltschrank mit dem Schlüsselschalter (der üblicherweise immer steckt :)), damit nur die Servicetechniker das Ganze bedienen können.
 
Zuletzt bearbeitet:
Du müsstest (...) ständig Angst haben, daß Du Deine Anlage zu Schrott kaputtsteuerst.
Offensichtlich hat er keine Angst.

Die Variablen "ByteNr", "BitNr" und "Aktivieren" werden von PC-Seite aus direkt in den zum FB gehörenden DB geschrieben:

Code:
//S7Netplus Ausgang aktivieren:
PLC.Write("DB200.DBD0", ByteNr);    //ByteNr - DWord
PLC.Write("DB200.DBD4", BitNr);     //BitNr - DWord
PLC.Write("DB200.DBX8.0", true);    //Aktivieren - Merker

//S7Netplus Ausgang deaktivieren:
PLC.Write("DB200.DBX8.0", false);    //Aktivieren - Merker
Und hiermit wird dann auch noch jeder zum kaputtsteuern der Anlage eingeladen, der Zugriff zum Netzwerk der SPS hat. Da braucht ein Bösewicht nur den Stromlaufplan der Anlage, um gezielt Schäden anzurichten oder die Produktion von Ausschuss zu forcieren, und muß noch nichtmal in dem Gebäude sein wo die Anlage steht.
 
Warum dann nicht in die "Aktorbausteine" ne ordentliche Handebene mit einbauen?
Oder schreibt Ihr die Ausgänge aus irgendwelchen Spaghetticodeverknüfungsorgien heraus? 🤔
 
Zurück
Oben