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



## MatthiasSt (9 Dezember 2019)

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


----------



## Blockmove (9 Dezember 2019)

Warum nicht im HMI eine INT dem Schaltern zuweisen?
Eigentlich die einfachste Lösung


----------



## oliver.tonn (9 Dezember 2019)

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.


----------



## StructuredTrash (9 Dezember 2019)

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:

```
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
```


----------



## Blockmove (9 Dezember 2019)

oliver.tonn schrieb:


> 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.



Da brauchst du nicht mal nen Radio-Button.


----------



## StructuredTrash (9 Dezember 2019)

Blockmove schrieb:


> Warum nicht im HMI eine INT dem Schaltern zuweisen?
> Eigentlich die einfachste Lösung



Stimmt, geht aber nur in Codesys V3. In V2 muss man sich noch mit der Bool-Tastfunktion behelfen.


----------



## Blockmove (9 Dezember 2019)

StructuredTrash schrieb:


> Stimmt, geht aber nur in Codesys V3. In V2 muss man sich noch mit der Bool-Tastfunktion behelfen.



Stimmt 
Dann ist dein kleiner "Umweg" sicher die eleganteste Lösung


----------



## hucki (9 Dezember 2019)

StructuredTrash schrieb:


> 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:
> 
> ```
> ...


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:

```
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.


----------



## Blockmove (9 Dezember 2019)

Hucki es dürften Buttons mit Tastfunktion sein.


----------



## Onkel Dagobert (9 Dezember 2019)

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  !


----------



## KLM (9 Dezember 2019)

> Stimmt, geht aber nur in Codesys V3. In V2 muss man sich noch mit der Bool-Tastfunktion behelfen.



Geht auch in CS2.3
Objekt Eigenschaften > Eingabe > Programm ausführen > ASSIGN > Variable := Wert für Integer
Einmal Anlegen und dann in den Eigenschaften der Kopie nur den Wert im Text ändern: INTERN ASSIGN PLC_PRG.iInt:=(1)


----------



## StructuredTrash (9 Dezember 2019)

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 (9 Dezember 2019)

Blockmove schrieb:


> Hucki es dürften Buttons mit Tastfunktion sein.



Also zumindest hier steht für mich was anderes:


MatthiasSt schrieb:


> 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.


----------



## StructuredTrash (9 Dezember 2019)

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 (9 Dezember 2019)

> 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.


----------



## Blockmove (9 Dezember 2019)

hucki schrieb:


> Also zumindest hier steht für mich was anderes:



Wie sagte mal ein früherer Chef von mir: "Lassen Sie mich in Ruhe mit ihren Details rund um ihre Bits und Bytes. Machen Sie einfach"
Auch ein Taster schaltet ein Signal 

Du hast natürlich Recht


----------



## StructuredTrash (9 Dezember 2019)

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.


----------



## MatthiasSt (18 Dezember 2019)

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


----------

