TIA Nie mehr als zwei Ausgänge setzen können.

bkizilkaya

Level-1
Beiträge
93
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Tag Forum

In einem Thread in eurem Forum habe ich eine Spannende Aufgabe gesehen. Ich weiss leider nicht mehr wo es ist, deshalb kann ich euch den Link angeben.
Ich habe 5 Ausgänge und 5 Schalter. Die Ausgänge funktionieren Abhängigkeit von den Schaltern d.h. wenn ich jetzt den Schalter 1 betätige dann sollte Ausgang 1 anfangen zu leuchten (sind keine LED’s, sondern ich werde die Ausgänge via Variablentabellen simulieren) und wenn ich den 2 Schalter betätig dann sollte Ausgang 2 leuchten und usw. Aber es dürfen nur immer 2 Leuchten d.h. wenn ich jetzt zum Beispiel Schalter 1 betätige und Schalter 2 betätige dann sollten die beiden Ausgänge leuchten, aber wenn ich jetzt Schalter 3 Betätige dann darf mir der Ausgang 3 nicht leuchten, weil schon 2 betätigt sind. Wenn ich jetzt zum Beispiel Schalter 1 deaktiviere dann leuchtet automatisch der Ausgang 3, weil es ja in der Warteschlange zu Oberst war.

Mein Lösungsansatz:
Ich werde zuerst die Schalter in Zahlenformate umwandeln d.h. wenn ich den Schalter 1 betätige dann nimmt zum Beispiel das Merkerwort den Wert 1. Schalter 2 übernimmt dann 2 und usw.
Danach werde ich mit Vergleicher arbeiten und die Warteschlange wird dann eine DB.
Es ist eine Übungsaufgabe, deshalb brauche ich keine Hardware ich werde es mit der virtuellen SPS in der TIA simulieren.
Bevorzugte Sprache: SCL :D
Im Anhang findet ihr noch ein kleines Struktogramm, aber nur provisorisch.

Ich möchte von euch kein fertiges Programm sondern ob dieser Lösungsansatz gut ist, ob er machbar ist und ob es einen bessere gibt?

Gruss
 

Anhänge

  • Augänge.doc
    22,5 KB · Aufrufe: 33
Du könntest alles Schalterzustände zyklisch in ein Array laden. Dann kannst du eine Schleife machen, die abgebrochen wird, wenn 2 mal ein Schaltzustand 1 vorliegt. Oder gleich die Anzahl Einzustand im Array zählen, ist die Anzahl grösser als gleich 2, darf kein neue Schalter geschalter werden.
Wäre meine erste Idee für einen Lösungsansatz. Als Code sollte das auch machbar sein, vorallem in SCL gut.
Dann kannst du noch reinbauen, falls doch mal 2 Schalter an sind, wird einer ausgemacht usw. um Fehlzustände auszugleichen.
Und deine Warteschlage würde ich auch in ein Array packen und wie du geschrieben hast jeder Schalter bekommt eine eindeutige id.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für deine Antwort

Deine Idee finde ich auch toll. Ich bin zurzeit deine Idee zu umzusetzen:

Code:
FUNCTION_BLOCK "Baustein_1"


VERSION : 0.1
 VAR_INPUT 
      schalter_0 : Bool;
      schalter_1 : Bool;
      schalter_2 : Bool;
      schalter_3 : Bool;
   END_VAR
 VAR_OUTPUT 
      ausgang_0 : Bool;
      ausgang_1 : Bool;
      ausgang_2 : Bool;
      ausgang_3 : Bool;
      besetzt : Bool;
   END_VAR
 VAR 
      Schalterzustände { S7_HMI_Visible := 'False'} : Array [0 .. 3] of Bool;
   END_VAR
 VAR_TEMP 
      x : Int;
      y : Int;
   END_VAR


BEGIN
	// Schalterzustände ins Array abspeichern
	#Schalterzustände [0]   := #schalter_0;
	#Schalterzustände [1]   := #schalter_1;
	#Schalterzustände [2]   := #schalter_2;
	#Schalterzustände [3]   := #schalter_3;
		
	WHILE #y <> 2 DO
	  FOR #x := 0 TO 3 BY 1 DO
	    IF #Schalterzustände[#x] = 1 THEN
	      #y := #y + 1;
	    END_IF;
	  END_FOR;
	END_WHILE;
	
	IF #y = 2 THEN
	  #besetzt := 1;
	END_IF;
	
	// Ausgänge definieren
	#ausgang_0 := #Schalterzustände [0];
	#ausgang_1 := #Schalterzustände [1];
	#ausgang_2 := #Schalterzustände [2];
	#ausgang_3 := #Schalterzustände [3];
	
END_FUNCTION_BLOCK
 
Stabelpuffer mit 5 Ebenen. Nur Ebenen 1 und 2 aktiviert eine Lampe.
Wenn eine Schalter aktiviert wird, wird das dazugehörige Nummer zu den ersten freien Ebene hingefügt.
Wenn eine Schalter deaktiviert wird, wird es von den Puffer entfernt, und die Werte in die obere Ebenen fallen einen Ebene runter.

//Schalter 1 wird aktiviert, dann 2, dann 3 -->

0
0
3 (ignoriert)
..
2 (lampe 2 aktiv)
1 (lampe 1 aktiv)


// Schalter 2 wird deaktiviert, -->

0
0
0
..
3 (Lampe 3 aktiv)
1 (Lampe 1 aktiv)


Wenn man es so visualisiert hat, wird das programieren ein Kinderspiel.
 
Danke für deine Antwort ich habe es mir auch visuell dargestellt. Wenn ich es visuell darstelle ist es mir ganz klar aber das mit dem puffer verstehe ich nicht so ganz. Kannst du es mir kurz erklären.

Gruss
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Tag Forum

In einem Thread in eurem Forum habe ich eine Spannende Aufgabe gesehen. Ich weiss leider nicht mehr wo es ist, deshalb kann ich euch den Link angeben.
Das war wohl hier (mit Vorspiel "2 aus 4" bis Post #30) und mit der LOGO! m.M.n. etwas schwieriger bzw. nur mit Kompromissen umzusetzen.
;)



Ansonsten würde ich es genau so machen, wie JesperMP es beschrieben hat:

Eingang 1 neu gesetzt?
- auf Stelle 5 einfügen,
- anschließend soweit wie möglich im Speicher nach unten schieben
Oder Eingang 1 neu zurückgesetzt
- raussuchen und
- aus Speicher löschen
- Rest nachschieben

Eingang 2 ... bis 5 Vorgang von Eingang 1 wiederholen

Inhalt von Stelle 1 und 2 im Speicher wenn möglich einschalten
 
Zuletzt bearbeitet:
EDIT: Wusst ichs doch!.. Wär j auch zu einfach gewesen... :)

Ich habe 5 Ausgänge und 5 Schalter.
Die Ausgänge funktionieren Abhängigkeit von den Schaltern
es dürfen nur immer 2 Leuchten d.h. wen

wenn ich jetzt zum Beispiel Schalter 1 betätige und Schalter 2 betätige dann sollten die beiden Ausgänge leuchten, aber wenn ich jetzt Schalter 3 Betätige dann darf mir der Ausgang 3 nicht leuchten, weil schon 2 betätigt sind. Wenn ich jetzt zum Beispiel Schalter 1 deaktiviere dann leuchtet automatisch der Ausgang 3, weil es ja in der Warteschlange zu Oberst war.

Sehr interessant, hab mir auch was ausgedacht.
Vielleicht habe ich die Anforderungen nicht richtig verstanden, meine Lösung kommt mir irgendwie zu einfach vor.

1. Ich habe einen Wert der mir die Anzahl der gedrückten Taster als int liefert (1-5)
2. Ich übertrage den Zustand der Taster nur auf die Ausgänge wenn dieser Wert <=2 ist.
(Wenn die Ein/Ausgänge bitmäßig gut liegen könnte man sogar L EBx --> T ABx machen)

Beispiel:
1. Schalter EIN (Wert 1) - Alle Eingänge auf Ausgänge geschrieben - Ausgang 1 leuchtet
2. Schalter EIN (Wert 2) - Alle Eingänge auf Ausgänge geschrieben - Ausgang 1 und 2 leuchten
3. Schalter EIN (Wert 3) - Nichts wird unternommen - Ausgang 1 und 2 leuchten
1. Schalter AUS (Wert 2) - Alle Eingänge auf Ausgänge geschrieben - Ausgang 2 und 3 leuchten

Kanns das sein oder hab ich was vergessen? Irgendwie kommt es mir so vor als würd ich was hier nicht richtig kapieren....
 
Zuletzt bearbeitet:
sein oder hab ich was vergessen? Irgendwie kommt es mir so vor als würd ich was hier nicht richtig kapieren....
Ja!
Z.B. folgendes Szenario bei Dir:
Schalter 1 Ein - Lampe 1 ein
Schalter 2 Ein - Lampe 2 ein
Schalter 4 Ein - nichts weiter
Schalter 3 Ein - nichts weiter
Schalter 1 Aus - ? ? ?

Und dann noch die Reihenfolge beim Einschalten von max. 5 Schaltern und die entsprechende Reihenfolge beim Aus-/Nachschalten.

Was passiert, wenn 3 oder mehr Schalter gleichzeitig betätigt werden bzw. beim Einschalten schon an sind?


Wenn min. 2 Schalter an sind, sollen auch 2 Ausgänge an sein und nicht nur einer oder gar keiner. Bei Gleichzeitigkeit hat Schalter 1 die höchste Priorität ...
 
Zuletzt bearbeitet:
Das mit dem Puffer verstehe ich schon, aber wie realisiert man so ein Puffer oder besser gesagt wie realisiert man abspeichern eines Schalter in den Puffer?

Könnt ihr mir weiterhelfen?

gruss
 
Ich wurde auch nach SCL tendieren.

Man kann schnell ein pseude-code schreiben, und wenn das richtig aussieht hat man fast schon den SCL code.


Code:
FUNCTION_BLOCK Stabel_Puffer_2_von_5
[COLOR=#333333]
VAR_INPUT
   Schalter_1 : BOOL ;
[/COLOR][COLOR=#333333]   Schalter_2 : BOOL ;
[/COLOR][COLOR=#333333]   Schalter_3 : BOOL ;
[/COLOR][COLOR=#333333]   Schalter_4 : BOOL ;
[/COLOR][COLOR=#333333]   Schalter_5 : BOOL ;
[/COLOR][COLOR=#333333]END_VAR

VAR_OUTPUT
  Lampe_1 : BOOL ;
[/COLOR][COLOR=#333333]  Lampe_2 : BOOL ;
[/COLOR][COLOR=#333333]  Lampe_3 : BOOL ;
[/COLOR][COLOR=#333333]  Lampe_4 : BOOL ;
[/COLOR][COLOR=#333333]  Lampe_5 : BOOL ;[/COLOR][COLOR=#333333]
END_VAR 

VAR_TEMP
  i , j : INT ;
  Plaziert , Entfernt : BOOL ;
END_VAR


VAR
[/COLOR][COLOR=#333333]   Stabel : ARRAY[1..5] of INT ; [/COLOR][COLOR=#333333]// Stabelpuffer mit 5 Ebenen. [/COLOR][COLOR=#333333]
[/COLOR][COLOR=#333333]   Schalter_Zustand : ARRAY[1..5] of BOOL ;[/COLOR][COLOR=#333333]
   Schalter_Flanke : ARRAY[1..5] of BOOL ;
[/COLOR][COLOR=#333333]   Schalter_Flanke_Speicher : ARRAY[1..5] of BOOL ;[/COLOR][COLOR=#333333]
[/COLOR][COLOR=#333333]   Lampe_Zustand : ARRAY[1..5] of BOOL ;[/COLOR][COLOR=#333333]
END_VAR

[/COLOR][COLOR=#333333]//Wenn eine Schalter aktiviert wird, 
[/COLOR][COLOR=#333333]Schalter_Zustand[1] := Schalter_1 ;[/COLOR][COLOR=#333333]
[/COLOR][COLOR=#333333]Schalter_Zustand[2] := Schalter_2 ;
[/COLOR][COLOR=#333333]Schalter_Zustand[3] := Schalter_3 ;
[/COLOR][COLOR=#333333]Schalter_Zustand[4] := Schalter_4 ;
[/COLOR][COLOR=#333333]Schalter_Zustand[5] := Schalter_5 ;
[/COLOR][COLOR=#333333]
[/COLOR][COLOR=#333333]FOR i:=1 TO 5 BY 1 DO
  [/COLOR][COLOR=#333333]Schalter_Flanke[i] := [/COLOR][COLOR=#333333]Schalter_Zustand[i] AND NOT [/COLOR][COLOR=#333333]Schalter_Flanke_Speicher[/COLOR][COLOR=#333333][i] ;
[/COLOR][COLOR=#333333]  Schalter_Flanke_Speicher[/COLOR][COLOR=#333333][i] := [/COLOR][COLOR=#333333]Schalter_Zustand[i] ;
[/COLOR][COLOR=#333333]  IF [/COLOR][COLOR=#333333]Schalter_Flanke[i] THEN
[/COLOR][COLOR=#333333]// [/COLOR][COLOR=#333333]wird das dazugehörige Nummer zu den ersten freien Ebene hingefügt.[/COLOR][COLOR=#333333]
    Plaziert := FALSE ;
[/COLOR][COLOR=#333333]    FOR j:=1 TO 5 BY 1 DO
      IF Stabel[j]=0 AND NOT Plaziert THEN 
        [/COLOR][COLOR=#333333]Stabel[j] :=i  ;
[/COLOR][COLOR=#333333]        Plaziert := TRUE ;
      END_IF ;
    END_FOR ;
  END_IF ;
END_FOR ;

[/COLOR]
[COLOR=#333333]// Wenn eine Schalter deaktiviert wird, wird es von den Puffer entfernt, und die Werte in die obere Ebenen fallen einen Ebene runter.
[/COLOR][COLOR=#333333]FOR i:=1 TO 5 BY 1 DO[/COLOR]
[COLOR=#ff0000](*
Nun habe ich kein Zeit mehr.
Aber ich denke du kapierst den Idee.
*)[/COLOR]

[COLOR=#333333]// Nur Ebenen 1 und 2 aktiviert eine Lampe.[/COLOR]
Lampe_Zustand[1] := FALSE ;[COLOR=#333333]
[/COLOR]Lampe_Zustand[2] := FALSE ;
Lampe_Zustand[3] := FALSE ;
Lampe_Zustand[4] := FALSE ;
Lampe_Zustand[5] := FALSE ;[COLOR=#333333]
[/COLOR]Lampe_Zustand[Stabel[1]] := TRUE ; [COLOR=#ff0000]// Hier fehlt es ein abfangen von wenn eine ebene Leer ist (Stabel[1] = 0)[/COLOR]
Lampe_Zustand[Stabel[2]] := TRUE ;

Lampe_1 := Lampe_Zustand[1] ;
Lampe_2 := Lampe_Zustand[2] ;
Lampe_3 := Lampe_Zustand[3] ;
Lampe_4 := Lampe_Zustand[4] ;
Lampe_5 := Lampe_Zustand[5] ;

END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
die Array die du hast : Schalter_Flanke_Speicher, Schalter_Flanke.
Die brauchst man doch nicht oder was haben diese für den Zweck. Sind die etwa für die erkennung ob sie frisch aktiviert worden sind.
 
Du hast in dein Bescreibung erklärt das die Schalter die Ausgänge aktiveren soll, abhängig von welchen Reihenfolge sie aktiviert werden.
Deswegen muss man den Flanke erkennen wenn eine Schalter aktiviert werden. ("Wenn ein Schalter aktiviert wird").
Ohne diese Bedingung in deine Beschreibung wäre das ganze viel viel einfacher. Aber deswegen auch interessanter.
 
ok verstehe
du hast im ersten schritt einen positiven flanken gewertet

und jetzt beim deaktivieren muss ich halt die negative flanke auswerten.

muss ich für die negative flanke nur die Not ein bisschen tauschen oder wie geht das? habe noch nie eine negativeflanke auswertung gemacht im SCL
 
ich habe es einmal so gemacht:

Code:
// Puffer eintrag löschen
FOR #x:=1 TO 5 BY 1 DO  
  IF #Schalter_zustand[#x] = 0 THEN
// wird die Schalter_ID in der entsprechenden Zelle gelöscht und die eins höhere Zelle wird dann verschoben in die tiefste Zelle
    #Entfernt := false ;
    FOR #y:=1 TO 5 BY 1 DO
      IF #Puffer[#y] < 0 AND NOT #Entfernt THEN 
        #Puffer[#y] := #Puffer[#y + 1]  ;
        #Entfernt := TRUE ;
      END_IF ;
    END_FOR ;
  END_IF ;
END_FOR ;

aber irgendwie geht es nicht wenn ich die beiden programmteile separat teste dann funktioniert es
 
Du musst weiter arbeiten.
Du kriegst es bald.
In dein Code, wenn eine #Schalter_zustand[#x] = false, egal welche, ziehst du nur den Pufferzelle 2 nach unten nach Zelle 1, die andere nicht.


Hinweis:
IF #Schalter_zustand[#x] = 0 THEN
muss man nach diesen Nummer (x) in den Stabelpuffer suchen, und wenn es gefunden wird, dann die Obere Zellen nach unten ziehen (wobei gleichzeitig den Zelle mit x gelöscht wird).

Und eine Schönheitssache:
IF #Schalter_zustand[#x] = 0 THEN // ok
IF #Schalter_zustand[#x] = FALSE THEN // besser
IF NOT #Schalter_zustand[#x] THEN // best
 
Zuletzt bearbeitet:
ich komme nicht weiter bei mir sind die einträge im array immer noch geschrieben obwohl der schalter deaktiviert ist.

könnt ihr mir vielleicht helfen


gruss
 
Zurück
Oben