6 große Lüfter dürfen nicht gleichzeitig ein, wenn Anforderung von der Temperatur kommt, sonst fliegen die Sicherungen

Zuviel Werbung?
-> Hier kostenlos registrieren
Diese Aufgabe wäre wieder eine Gelegenheit für einen "Programmierwettbewerb"! ;)
Wieviele Merker und Timer benötigt man, um das gleichzeitige Starten der 6 Gebläse sicher zu verhindern?

Wie wärs, den Preis nicht für die geringste Anzahl auszuloben, sondern für die schönste, also einfachste, also nachvollziehbarste Lösung?
 
Meine Idee wären 6 Positiv-Flankenauswertungen der jeweiligen Startbefehle der Ventilatoren, die einen Merker für die Einschaltfreigabe rücksetzen.
Der Merker wird negiert per TON abgefragt und nach eingestellter Zeit wieder gesetzt.

Die Einschaltfreigabe als Bedingung für den Start eines Ventilators und gebrückt durch die Selbsthaltung.
 
Meine Idee wären 6 Positiv-Flankenauswertungen der jeweiligen Startbefehle der Ventilatoren, die einen Merker für die Einschaltfreigabe rücksetzen.
Der Merker wird negiert per TON abgefragt und nach eingestellter Zeit wieder gesetzt.
Dies sperrt nicht das mehrere Lüfter auf einmal startet.
Man muss eine Begrenzer vorher machen der nur 1 Startbefehl erlaubt.

Wie ich es sehe, gibt es 3 Aufgaben.
1. Entscheiden welche Lüfter gestartet werden muss.
2. Nur 1 Startbefehl darf auf Einmal aktiviert werden.
3. Wenn ein Startbefehl aktiviert ist (Flanke) muss einen Zeit ablaufen bevor die nächste Startbefehl aktiviert werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Diese Aufgabe wäre wieder eine Gelegenheit für einen "Programmierwettbewerb"! ;)
Wieviele Merker und Timer benötigt man, um das gleichzeitige Starten der 6 Gebläse sicher zu verhindern?
Sollte doch keinerlei Merker und Timer vonnöten sein. Die „Merker“ sind die Ausgänge/Eingänge und über eine Zyklus Zeit von 1-5s spart man sich den Timer.

Code:
IF     (Schalter1 <> Luefter1 )      THEN
Luefter1:=Schalter1;  
JMP Ende;  
END_IF

IF     (Schalter2 <> Luefter2 )      THEN
Luefter2:=Schalter2;  
JMP Ende;  
END_IF

IF     (Schalter3 <> Luefter3 )      THEN
Luefter3:=Schalter3;  
JMP Ende;  
END_IF

IF     (Schalter4 <> Luefter4 )      THEN
Luefter4:=Schalter4;  
JMP Ende;  
END_IF

IF     (Schalter5 <> Luefter5 )      THEN
Luefter5:=Schalter5;  
JMP Ende;  
END_IF

IF     (Schalter6 <> Luefter6 )      THEN
Luefter6:=Schalter6;  
JMP Ende;  
END_IF


Ende:

Wie wärs, den Preis nicht für die geringste Anzahl auszuloben, sondern für die schönste, also einfachste, also nachvollziehbarste Lösung?

Ja, das wäre auch eine gute Idee, aber viel einfacher und nachvollziehbarer geht es vermutlich nicht.
 
Wenn alle Ventilatoren anlaufen sollen, startet der 1te und setzt dabei die Freigabe für alle weiteren Ventilatoren zurück.
Ich lese es als du hast eine Freigabe pro Ventilator, und wenn 1 startet werden die Freigabes für 2-6 zurückgesetzt.
Wenn 2 startet werden die Freigabes für 3-6 zurückgesetzt. Usw.
Das war in den vorigen Beitrag nicht ganz klar.
Meine Idee wären 6 Positiv-Flankenauswertungen der jeweiligen Startbefehle der Ventilatoren, die einen Merker für die Einschaltfreigabe rücksetzen.
[..]
Die Einschaltfreigabe als Bedingung für den Start eines Ventilators und gebrückt durch die Selbsthaltung.

Nur ein Beispiel davon dass man ganz deutlich die Funktionalität definieren muss.
 
Habe die gleiche Aufgabenstellung zuweilen bei Maschinen mit grossen Servomotoren mit mechanischer Haltbremse. Diese Bremsen haben teils einen recht grossen Einschaltstrom wodurch wenn zufällig alle Servoantriebe die Bremsen zeitgleich lüften, die Versorgungsspannung kurz einbrechen liess.

Hatte mir daher mal einen FB gemacht, dessen Logik sicher stellen sollte, dass wenn möglich -sofort- eingeschaltet wird, aber wenn die Übergeordnete Logik mehrere Aktoren/Antriebe gleichzeitig aktiviert, durch den FB automatisch ein (priorisiertes) schrittweises Einschalten erfolgt.

Der Timer definiert die Zeitspanne des erhöhten Strombedarfs bei Aktivierung des Aktors.

Möglicherweise nicht der eleganteste Code, aber funktioniert ;-)

FB Deklarationsteil:
{attribute 'hide_all_locals'}
(*

**FB passing boolean inputs to outputs, yet prevents simultaneous switching on of multiple outputs**

This FB monitors ``bSigIn1..bSigIn5`` and passes their state instantly to the corresponding outputs ``bSigOut1..bSigOut5``
unless one ore more of the inputs switches on at the same time. In that case, this FB switches only the output with the
lowest number on instantly and delays switching on other outputs by ``tDelay``. If multiple inputs become TRUE at once,
this behaviour will occur with one output after another, this the maximum delay caused by this FB occurs when all 5 inputs
turn TRUE simultaneously and will then be 4 times ``tDelay``, occuring on ``bSigOut5``.
The highest number has the lowest priority.

Switching off always occurs instantly, regardless of how many input signals change simultaneously.


+-----------+-----------------------------------------------------------------------------------------+
| | Prevention of fuse-tripping |
+===========+=========================================================================================+
| |Tip| | Typical use for this FB is prevention of fuse-tripping. If devices with high switch-on |
| | current being connected to a single fuse, this FB ensures that the devices are switched |
| | on with a slight delay. |
+-----------+-----------------------------------------------------------------------------------------+

.. |Tip| image:: ../../LibPics/Signs/Sign_064P_Tip.png


*)

FUNCTION_BLOCK FB_BlockSimultaneousOn // FB passing boolean inputs to outputs, yet prevents simultaneous switching on of multiple outputs
VAR_INPUT
bSigIn1 : BOOL; // Input signal 1 (highest priority)
bSigIn2 : BOOL; // Input signal 2
bSigIn3 : BOOL; // Input signal 3
bSigIn4 : BOOL; // Input signal 4
bSigIn5 : BOOL; // Input signal 5 (lowest priority)
tDelay : TIME; // Delay time between switching multiple outputs on
END_VAR
VAR_OUTPUT
bSigOut1 : BOOL; // Output signal 1
bSigOut2 : BOOL; // Output signal 2
bSigOut3 : BOOL; // Output signal 3
bSigOut4 : BOOL; // Output signal 4
bSigOut5 : BOOL; // Output signal 5
bDelaying : BOOL; // Output signal 6
END_VAR
VAR
fbDelaying : TP;
END_VAR
FB Code:
IF bSigIn1 AND (NOT bSigOut1) AND (NOT fbDelaying.Q) THEN
bSigOut1:=TRUE;
fbDelaying(IN:=TRUE,PT:=tDelay);
END_IF;
IF bSigIn2 AND (NOT bSigOut2) AND (NOT fbDelaying.Q) THEN
bSigOut2:=TRUE;
fbDelaying(IN:=TRUE,PT:=tDelay);
END_IF;
IF bSigIn3 AND (NOT bSigOut3) AND (NOT fbDelaying.Q) THEN
bSigOut3:=TRUE;
fbDelaying(IN:=TRUE,PT:=tDelay);
END_IF;
IF bSigIn4 AND (NOT bSigOut4) AND (NOT fbDelaying.Q) THEN
bSigOut4:=TRUE;
fbDelaying(IN:=TRUE,PT:=tDelay);
END_IF;
IF bSigIn5 AND (NOT bSigOut5) AND (NOT fbDelaying.Q) THEN
bSigOut5:=TRUE;
fbDelaying(IN:=TRUE,PT:=tDelay);
END_IF;
fbDelaying(IN:=FALSE,PT:=tDelay,Q=>bDelaying);
IF NOT bSigIn1 THEN
bSigOut1:=FALSE;
END_IF;
IF NOT bSigIn2 THEN
bSigOut2:=FALSE;
END_IF;
IF NOT bSigIn3 THEN
bSigOut3:=FALSE;
END_IF;
IF NOT bSigIn4 THEN
bSigOut4:=FALSE;
END_IF;
IF NOT bSigIn5 THEN
bSigOut5:=FALSE;
END_IF;
 
Sollte doch keinerlei Merker und Timer vonnöten sein. Die „Merker“ sind die Ausgänge/Eingänge und über eine Zyklus Zeit von 1-5s spart man sich den Timer.

Code:
IF     (Schalter1 <> Luefter1 )      THEN
Luefter1:=Schalter1; 
JMP Ende; 
END_IF

IF     (Schalter2 <> Luefter2 )      THEN
Luefter2:=Schalter2; 
JMP Ende; 
END_IF

IF     (Schalter3 <> Luefter3 )      THEN
Luefter3:=Schalter3; 
JMP Ende; 
END_IF

IF     (Schalter4 <> Luefter4 )      THEN
Luefter4:=Schalter4; 
JMP Ende; 
END_IF

IF     (Schalter5 <> Luefter5 )      THEN
Luefter5:=Schalter5; 
JMP Ende; 
END_IF

IF     (Schalter6 <> Luefter6 )      THEN
Luefter6:=Schalter6; 
JMP Ende; 
END_IF


Ende:



Ja, das wäre auch eine gute Idee, aber viel einfacher und nachvollziehbarer geht es vermutlich nicht.

Wobei mir gerade einfällt das es etwas übersichtlicher geht, ich war sehr schlampig in der ersten Ausführung.

Code:
IF(Schalter1 <> Luefter1)THEN Luefter1:=Schalter1;JMP Ende; END_IF
IF(Schalter2 <> Luefter2)THEN Luefter2:=Schalter2;JMP Ende; END_IF
IF(Schalter3 <> Luefter3)THEN Luefter3:=Schalter3;JMP Ende; END_IF
IF(Schalter4 <> Luefter4)THEN Luefter4:=Schalter4;JMP Ende; END_IF
IF(Schalter5 <> Luefter5)THEN Luefter5:=Schalter5;JMP Ende; END_IF
IF(Schalter6 <> Luefter6)THEN Luefter6:=Schalter6;JMP Ende; END_IF

Ende:

Da stand bisher gar nciht das eine SPS verbaut ist!

Auf jeden Motorschütz einen pneumatischen Zeitblock der erst den nächsten nach x Sekunden freigibt -> fertig

Der Vorschlag hat mir auch gut gefallen :D
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... Wie ich es sehe, gibt es 3 Aufgaben.
1. Entscheiden welche Lüfter gestartet werden muss.
2. Nur 1 Startbefehl darf auf Einmal aktiviert werden.
3. Wenn ein Startbefehl aktiviert ist (Flanke) muss einen Zeit ablaufen bevor die nächste Startbefehl aktiviert werden.

Ihr macht es euch entschieden zu einfach :p . Ich ergänze mal:
4. Störumschaltung
5. Führungswechsel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wobei mir gerade einfällt das es etwas übersichtlicher geht, ich war sehr schlampig in der ersten Ausführung.

Code:
IF(Schalter1 <> Luefter1)THEN Luefter1:=Schalter1;JMP Ende; END_IF
IF(Schalter2 <> Luefter2)THEN Luefter2:=Schalter2;JMP Ende; END_IF
IF(Schalter3 <> Luefter3)THEN Luefter3:=Schalter3;JMP Ende; END_IF
IF(Schalter4 <> Luefter4)THEN Luefter4:=Schalter4;JMP Ende; END_IF
IF(Schalter5 <> Luefter5)THEN Luefter5:=Schalter5;JMP Ende; END_IF
IF(Schalter6 <> Luefter6)THEN Luefter6:=Schalter6;JMP Ende; END_IF

Ende:
Nicht schlecht, aber kann es sein, dass du mit der Lösung auch beim Ausschalten die Wartezeit hast?
Das kommt vermutlich nicht so gut.
Wenn du den Timer außerhalb der Funktion platzierst, wird er dennoch benötigt… ;)
 
Nicht schlecht, aber kann es sein, dass du mit der Lösung auch beim Ausschalten die Wartezeit hast?
Das kommt vermutlich nicht so gut.
Wenn du den Timer außerhalb der Funktion platzierst, wird er dennoch benötigt… ;)

Ja, beim ausschalten ist es genauso. Bei der ursprünglichen Aufgabenstellung war nicht viel zu lesen. Mich hat der Ehrgeiz gepackt bei der Aussage ein minimalistisches Programm mit möglichst wenig Merker und Timer, deshalb gibt es keine. Das erinnerte mich an die schöne Assembler Zeit mit 8 Bit Mikrocontrollern zurück und den 24Byte Arbeitsspeicher.
Ich persönlich würde es anders lösen.
 
Ich persönlich würde es anders lösen.
Ja, ich auch.
Code:
VAR
  Start_G1, Start_G2, Start_G3, Start_G4, Start_G5, Start_G6 : BOOL;
  Run_G1,   Run_G2,   Run_G3,   Run_G4,   Run_G5,   Run_G6   : BOOL;
  Startfreigabe : BOOL := TRUE;
  StartTimer : TON;
END_VAR

// Timer auf 60 Sekunden
StartTimer(IN := NOT Startfreigabe, PT := T#60s);

// Logik: nur starten, wenn Startfreigabe noch TRUE
IF Startfreigabe THEN
  IF Start_G1 AND NOT Run_G1 THEN
    Run_G1 := TRUE;
    Startfreigabe := FALSE;
  ELSIF Start_G2 AND NOT Run_G2 THEN
    Run_G2 := TRUE;
    Startfreigabe := FALSE;
  ELSIF Start_G3 AND NOT Run_G3 THEN
    Run_G3 := TRUE;
    Startfreigabe := FALSE;
  ELSIF Start_G4 AND NOT Run_G4 THEN
    Run_G4 := TRUE;
    Startfreigabe := FALSE;
  ELSIF Start_G5 AND NOT Run_G5 THEN
    Run_G5 := TRUE;
    Startfreigabe := FALSE;
  ELSIF Start_G6 AND NOT Run_G6 THEN
    Run_G6 := TRUE;
    Startfreigabe := FALSE;
  END_IF
END_IF

// Nach Ablauf des Timers: nächsten Start freigeben
IF StartTimer.Q THEN
  Startfreigabe := TRUE;
END_IF
 
Zuletzt bearbeitet:
Zurück
Oben