Elegante Lösung für Wechselschaltung in ST gesucht.

MatthiasSt

Member
Beiträge
22
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo, ich habe 5 Schalter auf dem HMI.
Jeder Schalter schaltet eine Funktion.
Wenn der erste Schalter gedrückt wird bleibt er aktiv.
Schalte ich einen anderen Schalter soll der gedrückte zurückgesetzt werden und der neue Schalter aktiv sein.

Über Endlose IF Anweisungen könnte man es lösen das schaut aber nicht gut aus.
Auch befinden sich die einzelnen, schaltbaren Funktionen in einer CASE Anweisung.

Ich hab schon überlegt die Schalter als INT mit einem Wert in eine Struct zu deklarieren.
Vermutlich kann ich sie dann nicht übers HMI schalten da kein BOOL.

Hat jemand eine Idee?

Stromstoßschaltung wollte ich auch vermeiden, wenn es anders ginge.

Danke
 

oliver.tonn

Well-known member
Beiträge
4.383
Punkte Reaktionen
721
Zuviel Werbung?
->Hier kostenlos registrieren
Gibt es bei der WAGO HMI keine Radio Buttons? In Verbindung mit der von Blockmove schon erwähnten INT-Variable würde das genau das machen was Du suchst, ohne das Du noch groß mit Bedingungen bei den einzelnen Elementen jonglieren musst.
 
Zuletzt bearbeitet:

StructuredTrash

Well-known member
Beiträge
1.124
Punkte Reaktionen
302
Nimm ein WORD, in dem Du für jeden Schalter ein Bit verwendest. Kannst Du dann bei der Tast-Eigenschaft z. B. als MyButton.0 (für Bit 0) eintragen.
Ganz ohne SPS-Code wird es aber wohl nicht gehen, z. B. so:
Code:
VAR
   VisuButtons:WORD;   (* Visu buttons, bitweise mit der Tast-Eigenschaft verknüpft *)
   OutputButtons:WORD;   (* Ausgabe-Buttons für die Steuerungsfunktion *)
END_VAR

IF (VisuButtons>0) AND (VisuButtons<>OutputButtons) THEN   (* Umschalten *)
   OutputButtons:=VisuButtons;
END_IF

CASE OutputButtons OF  (* Steuerungsfunktionen *)
   16#0001:
      MachDies();
   16#0002:
      MachDas();
(* usw. *)
END_CASE
 

hucki

User des Jahres 2014
Beiträge
5.765
Punkte Reaktionen
1.756
Nimm ein WORD, in dem Du für jeden Schalter ein Bit verwendest. Kannst Du dann bei der Tast-Eigenschaft z. B. als MyButton.0 (für Bit 0) eintragen.
Ganz ohne SPS-Code wird es aber wohl nicht gehen, z. B. so:
Code:
VAR
   VisuButtons:WORD;   (* Visu buttons, bitweise mit der Tast-Eigenschaft verknüpft *)
   OutputButtons:WORD;   (* Ausgabe-Buttons für die Steuerungsfunktion *)
END_VAR

IF (VisuButtons>0) AND (VisuButtons<>OutputButtons) THEN   (* Umschalten *)
   OutputButtons:=VisuButtons;
END_IF

CASE OutputButtons OF  (* Steuerungsfunktionen *)
   16#0001:
      MachDies();
   16#0002:
      MachDas();
(* usw. *)
END_CASE
Ich denke, das wird auf diesem Weg nicht ganz funktionieren:
Wenn man z.B. nur 2 Schalter hat und drückt den 1., bekommt man eine 1, damit kann die Funktion 1 ausgelöst werden.
Drückt man jetzt den 2., bekommt man eine 3 (weil ja 1 noch gedrückt ist) und löst die Funktion 3 aus (= Rücksetzen 1?).

Drückt man zuerst die 2., löst man die Funktion 2 aus.
Drückt man als nächstes die 1, bekommt man (wieder) die 3 (weil 2 ja noch gedrückt ist) und löst (wieder) die Funktion 3 aus (= Rücksetzen 1?).


IMHO muss man mit dem vorgeschlagenen WORD zusätzlich eine Flankenabfrage erstellen, wie PN/DP es in der FAQ zeigt und damit den vorher gedrückten Schalter zurücksetzen.
Ungetestet (und hoffentlich einigermaßen vernünftig von AWL zu ST transferiert) so in etwa:
Code:
VAR
   VisuButtons:WORD;   (* Visu buttons, bitweise mit der Tast-Eigenschaft verknüpft *)
   ButtonMerker:WORD;   (* Vergleichs- und Flanken-Word *)
END_VAR


#ButtonMerker := #VisuButtons AND NOT #ButtonMerker;    (* Flankenauswertung lt. PN/DP-FAQ *)
IF #ButtonMerker THEN                                   (* neuer Taster gedrückt? *)
    #VisuButtons := #ButtonMerker;                      (* nur neu gedrückten Taster behalten *)
END_IF;
#ButtonMerker := #VisuButtons;                          (* gedrückten Taster für nächsten Zyklus speichern *)


CASE #VisuButtons OF                                    (* Steuerungsfunktionen *)
    16#0001:
        MachDies();
    16#0002:
        MachDas();
    16#0004:
        MachJenes();
(* usw. *)
END_CASE
Ich geh' mal davon aus, dass man an der Visu nur einen Button und nicht mehrere gleichzeitig betätigen kann.
 

Onkel Dagobert

Well-known member
Beiträge
5.337
Punkte Reaktionen
1.123
Richtige Röhrenradio-Buttons für echte Kerle haben eine mechanische Verriegelung bzw. eine Schaltpause beim Signalwechsel. Ich schätze, in 95% unserer Fälle ist so etwas ebenfalls erforderlich, in den restlichen 5% nicht hinderlich. Also macht es euch nicht so einfach :ROFLMAO: !
 

StructuredTrash

Well-known member
Beiträge
1.124
Punkte Reaktionen
302
Zuviel Werbung?
->Hier kostenlos registrieren
Ja klar Tastfunktion. Hatte ich das nicht geschrieben?
Und auch richtig: Es dürfen nicht zwei Tasten gleichzeitig betätigt werden können. Das ist mir bei der Codesys-Targetvisu bisher aber auch noch nicht gelungen.

@KLM:
Da hast Du recht. Ein verborgener Schatz, vielleicht zu Unrecht etwas in Vergessenheit geraten.
 

hucki

User des Jahres 2014
Beiträge
5.765
Punkte Reaktionen
1.756

StructuredTrash

Well-known member
Beiträge
1.124
Punkte Reaktionen
302
Das ist die Funktionalität, die im SPS-Programm erreicht werden soll. Aber man muss dafür doch nicht zwangsläufig die Umschaltfunktion der Visu-Buttons nutzen. Selbst wenn man den Schaltzustand in den Visu-Buttons anzeigen möchte, kann man für den Farbwechsel ja die Bits von OutputButtons heranziehen.
 

KLM

Well-known member
Beiträge
399
Punkte Reaktionen
87
Zuviel Werbung?
->Hier kostenlos registrieren
Ja klar Tastfunktion. Hatte ich das nicht geschrieben?
Und auch richtig: Es dürfen nicht zwei Tasten gleichzeitig betätigt werden können. Das ist mir bei der Codesys-Targetvisu bisher aber auch noch nicht gelungen.

Die Funktion mit ASSIGN ist schaltend, d.h. der jeweilige Button bleibt dann auch gesetzt. Ob das tatsächlich nur bei der Flanke geschrieben wird, müsste man mal testen. Dann wäre auch ein gleichzeitiger Druck auf zwei Visu-Clients kein Problem. Es gibt trotz mehrerer Clients ja nur eine Variable, die nur einen Wert annehmen kann. Fall nicht bei der Flanke geschrieben wird, sondern zyklisch (kann ich mir aber nicht vorstellen), dann wäre es schon etwas tricky und man müsste applikativ eine Verriegelung einbauen (evtl. zeitliche Blockierung mit Flankenerkennung).

Da hast Du recht. Ein verborgener Schatz, vielleicht zu Unrecht etwas in Vergessenheit geraten.
Ja, etwas versteckt, aber immer wieder sehr hilfreich.
 

StructuredTrash

Well-known member
Beiträge
1.124
Punkte Reaktionen
302
Ich gehe mal davon aus, dass der TE zunächst die Umschaltfunktion der Visu-Buttons gewählt hat, weil der Schaltzustand ja erhalten bleiben soll. Dann ist er auf das Problem gestossen, dass er beim Umschalten den bisher gesetzten Button zurücksetzen muss, und deshalb hat er ja den Thread eröffnet.
Ich denke, dass die Umschaltfunktion der Visubuttons kein Must have für den TE ist, daher meine Lösung mit der Tastfunktion. Und mit dem Vorschlag von KLM steht auch noch eine Lösung bereit, die ohne zusätzlichen SPS-Code auskommt und zudem auch den letzten Rest an Unsicherheit (Mehrfach-Tasten) ausschliesst.
Wäre noch zu klären, ob eine einmal gewählte Funktion durch nochmaliges Drücken des Buttons wieder ausgeschaltet werden soll. In dem Fall wird es nicht ohne SPS-Code und auch nicht ohne Trigger gehen.
 
OP
M

MatthiasSt

Member
Beiträge
22
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo,
danke für die Zahlreichen Antworten.

Ich hab's ganz einfach mit einem XOR gelöst und einem Kopieren der Struct in eine andere Struct für den letzten Zustand.
Das XOR überwacht den Wechsel der Buttons.
Es ist leider bissel kniffelig da von 4 Tastern jeweils 2 zusammengehören. Der eine Führt eine Grundfunktionalität der andere eine Zusatzfunktionalität aus. Das Ganze dann zwei mal, deshalb 4 Taster.
Über die gemerkte Struct sehe ich dann im CASE Schritt was ich ausschalten muss und was nicht.
Danke
 
Oben