Jalousiesteuerung mit SCL - Rundungsproblem

sensei99

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
meine gesamtes Haus hängt an einer S7-300. Nun bin ich dabei, meine Jalousieautomatik (16 Stck.) zu verbessern. Grundgedanke ist, dass im ersten Schritt eine Sollstellung (0..100%, 0% ist oben) gebildet wird. Das funktioniert prima, mit Prioritäten usw.
Anschließend wird, falls die entsprechende Fahrt "enabled" ist, automatisch die Sollstellung angefahren. Auch das tuts im Grunde. Nur bei wenigen Kombinationen aus Laufzeit, Sollstellung, etc. gibt es Probleme, die ziuemlich sicher auf Rundungsfehler oder auf die Abfrage zum Stoppen (Sollstellung erreicht) zurück zuführen sind.
Die Spezialisten unter euch werden bestimmt im folgenden Programmcode einen Bug entdecken.
Ich wäre euch wirklich sehr dankbar, wenn ihr euch das mal ansehen würdet.
Das Ganze äußert sich so, dass die Jalousie beim Erreichen der Sollstellung "auf- und Abzappelt", eben um die Sollstellung herum. Immer +/- ein paar %.
Hier nun der Code:

FUNCTION FC12 : VOID
VAR_INPUT
LZAuf: REAL; // Laufzeit für 100% Auf
LZAb: REAL; // Laufzeit für 100% Ab
Takt: BOOL; // Impuls pro 0,5 Sekunden
// Automatikfreigabe
AutoATV: BOOL; // Generelle Freigabe der Automatikfunktionen
// Sperren bei niedriger Aussentemperatur
AussentempEN: BOOL; // Sperren bei niedriger Aussentemperatur ENABLE
AuTempSoll: REAL; // Sperren ab Aussentemperatur [°C]
AuTempIst: REAL; // Aktuelle Aussentemperatur [°C]
// Zwangsöffnen
ZwangAufEN: BOOL; // Zwangsöffnen (Einbruch..) ENABLE
ZwangAufATV: BOOL; // Zwangsöffnen (Einbruch..) AKTIV
// Zwangsschließen
ZwangZuEN: BOOL; // Zwangsschließen ENABLE
ZwangZuATV: BOOL; // Zwangsschließen AKTIV
// Sichtschutz
SichtEN: BOOL; // Sichtschutz ENABLE
SichtATV: BOOL; // Sichtschutz AKTIV
SichtSW: REAL; // Sollstellung für Sichtschutz [%]
// Innen aufheizen
InnenheizEN: BOOL; // Innen Aufheizen ENABLE
InTempSoll: REAL; // Innen Aufheizen bis Temperatur [°C]
InTempIst: REAL; // Aktuelle Temperatur [°C]
// Sonnenschutz
SonneEN: BOOL; // Sonnenschutz ENABLE
LuxSoll: REAL; // Sonnenschutz ab Helligkeit [Lux]
LuxIst: REAL; // Aktuelle Helligkeit [Lux]
SonneSW: REAL; // Sollstellung für Sonnenschutz [%]
SonneAbNach: INT; // Sonnenschutz Ab nach einer Verzögerungszeit [Sek.]
SonneAufNach: INT; // Sonnenschutz Auf nach einer Verzögerungszeit [Sek.]
// Handbetrieb
TastAuf: BOOL; // Taster für Hand Auf
TastAb: BOOL; // Taster für Hand Ab
// Rücksetzen in Automatikbetrieb
ResetAutoEN: BOOL; // Rücksetzen in Automatikbetrieb ENABLE
ResetAutoATV: BOOL; // Rücksetzen in Automatikbetrieb AKTIV
// Reset
ResetAll: BOOL; // Reset
END_VAR
VAR_IN_OUT
IstSt: REAL; // Iststellung in [%]
IstZtAuf: REAL; // Istzeit (aktuelle Fahrt) in [Sek.] Auf
IstZtAb: REAL; // Istzeit (aktuelle Fahrt) in [Sek.] Ab
SetSonne: REAL; // Zähler für Verzögerung Sonnenschutz
ResetSonne: REAL; // Zähler für Verzögerung Sonnenschutz wieder hochfahren
Auto: BOOL; // Aktuell Automatikbetrieb
Sonnenschutz: BOOL; // Aktuell Sonnenschutz
ProzAuf: REAL; // Soviel Prozent sind in 0,5 Sekunden gefahren in Auf
ProzAb: REAL; // Soviel Prozent sind in 0,5 Sekunden gefahren in Ab
SollZt: REAL; // SollZeit für aktuelle Fahrt in [Sek.]
SollSt: REAL; // Sollstellung in [%]
SonneAb: BOOL; // Freigabe Sonnenschutz
SonneAuf: BOOL; // Freigabe Sonnenschutz wieder hoch
END_VAR
VAR_OUTPUT
AusgangAuf: BOOL; // Ausgang für Auf
AusgangAb: BOOL; // Ausgang für Ab
HandAuf: BOOL; // Aktuell Fährt per Hand Auf
HandAb: BOOL; // Aktuell Fährt per Hand Ab
InnenAufheizen: BOOL; // Aktuell Innen Aufheizen
Sichtschutz: BOOL; // Aktuell Sichtschutz
ZwangAuf: BOOL; // Aktuell Zwang Auf
ZwangZu: BOOL; // Aktuell Zwnag Zu
Gesperrt: BOOL; // Aktuell gesperrt
END_VAR

// ****************************************************************************
// Reset
// ****************************************************************************
IF ResetAll=true THEN
AusgangAuf:=false;
AusgangAb:=false;
IstZtAuf:=0;
IstZtAb:=0;
SollSt:=0;
END_IF;
// ****************************************************************************
// Rückstellen in Automatikbetrieb
// Bei Hand- oder Winterbetrieb Automatikfunktionen deaktivieren
// Rückstellen automatisch oder per Hand (ResetAutoATV)
// ****************************************************************************
IF ResetAutoEN=true AND ResetAutoATV=true AND AutoATV=true THEN
Auto:=true;
ELSIF TastAuf=true OR TastAb=true OR AutoATV=false THEN
Auto:=false;
Sonnenschutz:=false;
END_IF;
// ****************************************************************************
// Fahren per Handbetrieb in Aufrichtung TASTBETRIEB
// ****************************************************************************
IF Auto=false AND TastAuf=true THEN
HandAuf:=true;
ProzAuf:=50/LZAuf;
AusgangAuf:=true;
IF Takt=true THEN
IstSt:=ROUND(IstSt-ProzAuf);
IF IstSt<=0 THEN
IstSt:=0;
END_IF;
END_IF;
ELSE
AusgangAuf:=false;
HandAuf:=false;
END_IF;
// ****************************************************************************
// Fahren per Handbetrieb in Abrichtung TASTBETRIEB
// ****************************************************************************
IF Auto=false AND TastAb=true THEN
HandAb:=true;
ProzAuf:=50/LZAb;
AusgangAb:=true;
IF Takt=true THEN
IstSt:=ROUND(IstSt+ProzAuf);
IF IstSt>=100 THEN
IstSt:=100;
END_IF;
END_IF;
ELSE
AusgangAb:=false;
HandAb:=false;
END_IF;
// ****************************************************************************
// Niedrigste Priorität: Sonnenschutz
// ****************************************************************************
// Verzögerung bis zum Beschatten
IF Auto=true AND SonneEN=true AND LuxIst>20000 AND LuxIst>LuxSoll THEN
ResetSonne:=0;
IF Takt=true THEN
SetSonne:=SetSonne+0.5;
END_IF;
IF SetSonne>=ROUND(SonneAbNach*60) THEN
SonneAb:=true;
SonneAuf:=false;
SetSonne:=0;
END_IF;
END_IF;
// Verzögerung bis zum Wiederhochfahren
IF Auto=true AND SonneEN=true AND LuxIst<LuxSoll THEN
SetSonne:=0;
IF Takt=true THEN
ResetSonne:=ResetSonne+0.5;
END_IF;
IF ResetSonne>=ROUND(SonneAufNach*60) THEN
SonneAuf:=true;
SonneAb:=false;
ResetSonne:=0;
END_IF;
END_IF;
IF Auto=true AND SonneEN=true AND SonneAb=true THEN
Sonnenschutz:=true;
SollSt:=SonneSW;
ELSIF Auto=true AND SonneEN=true AND SonneAuf=true THEN
SollSt:=0;
Sonnenschutz:=false;
END_IF;
IF Auto=true AND SonneEN=false THEN
SollSt:=0;
Sonnenschutz:=false;
END_IF;
// ****************************************************************************
// Innen aufheizen
// ****************************************************************************
IF Auto=true AND InnenHeizEN=true AND InTempIst<=InTempSoll THEN
InnenAufheizen:=true;
Sonnenschutz:=false;
SollSt:=0;
ELSE
InnenAufheizen:=false;
END_IF;
// ****************************************************************************
// Sichtschutz
// ****************************************************************************
IF Auto=true AND SichtEN=true AND SichtATV=true THEN
Sichtschutz:=true;
InnenAufheizen:=false;
Sonnenschutz:=false;
SollSt:=SichtSW;
ELSE
Sichtschutz:=false;
END_IF;
// ****************************************************************************
// Zwangsschließen
// ****************************************************************************
IF Auto=true AND ZwangZuEN=true AND ZwangZuATV=true THEN
ZwangZu:=true;
Sichtschutz:=false;
InnenAufheizen:=false;
Sonnenschutz:=false;
SollSt:=100;
ELSE
ZwangZu:=false;
END_IF;
// ****************************************************************************
// Zwangsöffnen
// ****************************************************************************
IF Auto=true AND ZwangAufEN=true AND ZwangAufATV=true THEN
ZwangAuf:=true;
ZwangZu:=false;
Sichtschutz:=false;
InnenAufheizen:=false;
Sonnenschutz:=false;
SollSt:=0;
ELSE
ZwangAuf:=false;
END_IF;
// ****************************************************************************
// Sperren wegen niedriger Aussentemperatur
// ****************************************************************************
IF Auto=true AND AussenTempEN=true AND AuTempIst<=AuTempSoll THEN
Gesperrt:=true;
ZwangAuf:=false;
ZwangZu:=false;
Sichtschutz:=false;
InnenAufheizen:=false;
Sonnenschutz:=false;
SollSt:=0;
ELSE
Gesperrt:=false;
//SollSt:=0;
END_IF;
// ****************************************************************************
// Bei Automatikbetrieb gewünschte Stellung anfahren
// ****************************************************************************
IF Auto=true THEN
// Ausgang auf gewünschten Sollwert fahren

// Sollstellung erreicht
IF AusgangAuf=true AND IstSt<=SollSt OR AusgangAb=true AND IstSt>=SollSt THEN
AusgangAuf:=false;
AusgangAb:=false;
IstZtAuf:=0.0;
IstZtAb:=0.0;
IstSt:=SollSt;
END_IF;

// Auffahren
IF SollSt<IstSt AND AusgangAb=false THEN
// Laufzeit für Auf festlegen
SollZt:=LZAuf/100*(IstSt-SollSt);
// Wieviel % entspricht 0.5 Sekunden?
ProzAuf:=50/LZAuf;
AusgangAuf:=true;
IF Takt=true THEN
IstZtAuf:=IstZtAuf+0.5;
IstSt:=IstSt-ProzAuf;
END_IF;
END_IF;
// Abfahren
IF SollSt>IstSt AND AusgangAuf=false THEN
// Laufzeit für Ab festlegen
SollZt:=LZAb/100*(SollSt-IstSt);
// Wieviel % entspricht 0.5 Sekunden?
ProzAb:=50/LZAb;
AusgangAb:=true;
IF Takt=true THEN
IstZtAb:=IstZtAb+0.5;
IstSt:=IstSt+ProzAb;
END_IF;
END_IF;
END_IF;


;
END_FUNCTION
 
Epsilon +/-5%

...ich habe sowas ähnliches mal in AWL gemacht - habe aber ein "EPSILON" von +/-5%.

D.h. wenn der Sollwert (nicht Tasterdruck) innerhalb des EPSILON ist, dann fährt NICHTS!!!

Wenn ich in die Endlagen fahre (mit Tasterdruck) dann fängt sich der Zähler immer wieder bei 0 oder 100 Prozent, weil er ja ggf. überläuft.


Gruß


P.S.

Da hast du ja einen gewaltigen Aufwand getrieben.

Der Nachteil eines FC ist, das IMMER alle Eingänge beschaltet werden müssen.
Deshalb habe ich das als MultiinstanzFB gemacht. Da braucht man auch nur einen DB für alles und kann erstmal Eingänge unbeschaltet lassen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Meiner Meinung nach löschst Du in den "Else-Zweigen" der Betriebsarten "Tasten Auf" und "Tasten Ab" immer den jeweiligen Ausgang Auf/Ab falls Du Dich in Automatik befindest.

Code:
[FONT="Courier New"]// ************************************************** **************************
// Fahren per Handbetrieb in Aufrichtung TASTBETRIEB
// ************************************************** **************************
IF [B]Auto=false AND TastAuf=true[/B] THEN
...
ELSE
  [B]AusgangAuf:=false;[/B]
  HandAuf:=false;
END_IF;
[/FONT]

sowie

Code:
[FONT="Courier New"]// ************************************************** **************************
// Fahren per Handbetrieb in Abrichtung TASTBETRIEB
// ************************************************** **************************
IF [B]Auto=false AND TastAb=true[/B] THEN
...
ELSE
  [B]AusgangAb:=false;[/B]
  HandAb:=false;
  END_IF;
[/FONT]

somit wird Dein STOP-Zweig

Code:
[FONT="Courier New"]// Sollstellung erreicht
IF [B]AusgangAuf=true[/B] AND IstSt<=SollSt OR [B]AusgangAb=true[/B] AND IstSt>=SollSt THEN
  AusgangAuf:=false; 
  AusgangAb:=false;
  IstZtAuf:=0.0;
  IstZtAb:=0.0;
  IstSt:=SollSt;
END_IF;
[/FONT]

nie durchlaufen.
Es wird lediglich, falls Du deine Zielposition genau triffst. Kein neuer "Fahrauftrag" gebildet.

Ich würde die Zielposition mit Toleranzen versehen und nicht generell im Automatikbetrieb die Ausgänge löschen.
 
Wenn Du den Code in Deiner Frage raus löschst in Step7 den Code neu kopierst und dann im Forum zwischen den Code Tags [ code ] [ /code ] (ohne die Leerzeichen an den Klammern) einfügst....

...werden wahrscheinlich mehr Leute mal über den Code schauen. ST/SCL ohne Einrückungen ist sehr unangenehm zu lesen.
 
Erstmal vielen Dank für euere Hilfe! Werde es morgen mal angehen.
Danke auch an zotos wegen dem Tipp mit der Lesbarkeit. Hier also noch mal alles in lesbarer Form:

Code:
// Funktion für Jalousieantriebe
FUNCTION FC12 : VOID
VAR_INPUT
  LZAuf:            REAL;     // Laufzeit für 100% Auf
  LZAb:             REAL;     // Laufzeit für 100% Ab
  Takt:             BOOL;     // Impuls pro 0,5 Sekunden
  // Automatikfreigabe
  AutoATV:          BOOL;     // Generelle Freigabe der Automatikfunktionen
  // Sperren bei niedriger Aussentemperatur
  AussentempEN:     BOOL;     // Sperren bei niedriger Aussentemperatur ENABLE
  AuTempSoll:       REAL;     // Sperren ab Aussentemperatur [°C]
  AuTempIst:        REAL;     // Aktuelle Aussentemperatur [°C]
  // Zwangsöffnen
  ZwangAufEN:       BOOL;     // Zwangsöffnen (Einbruch..) ENABLE
  ZwangAufATV:      BOOL;     // Zwangsöffnen (Einbruch..) AKTIV
  // Zwangsschließen
  ZwangZuEN:        BOOL;     // Zwangsschließen ENABLE
  ZwangZuATV:       BOOL;     // Zwangsschließen AKTIV
  // Sichtschutz
  SichtEN:          BOOL;     // Sichtschutz ENABLE
  SichtATV:         BOOL;     // Sichtschutz AKTIV
  SichtSW:          REAL;     // Sollstellung für Sichtschutz [%] 
  // Innen aufheizen 
  InnenheizEN:      BOOL;     // Innen Aufheizen ENABLE
  InTempSoll:       REAL;     // Innen Aufheizen bis Temperatur [°C]
  InTempIst:        REAL;     // Aktuelle Temperatur [°C]
  // Sonnenschutz
  SonneEN:          BOOL;     // Sonnenschutz ENABLE
  LuxSoll:          REAL;     // Sonnenschutz ab Helligkeit [Lux]
  LuxIst:           REAL;     // Aktuelle Helligkeit [Lux]
  SonneSW:          REAL;     // Sollstellung für Sonnenschutz [%] 
  SonneAbNach:      INT;      // Sonnenschutz Ab nach einer Verzögerungszeit [Sek.]
  SonneAufNach:     INT;      // Sonnenschutz Auf nach einer Verzögerungszeit [Sek.]
  // Handbetrieb
  TastAuf:          BOOL;     // Taster für Hand Auf
  TastAb:           BOOL;     // Taster für Hand Ab
  // Rücksetzen in Automatikbetrieb
  ResetAutoEN:      BOOL;     // Rücksetzen in Automatikbetrieb ENABLE
  ResetAutoATV:     BOOL;     // Rücksetzen in Automatikbetrieb AKTIV 
  // Reset
  ResetAll:         BOOL;     // Reset
END_VAR
VAR_IN_OUT
  IstSt:            REAL;     // Iststellung in [%]
  IstZtAuf:         REAL;     // Istzeit (aktuelle Fahrt) in [Sek.] Auf
  IstZtAb:          REAL;     // Istzeit (aktuelle Fahrt) in [Sek.] Ab
  SetSonne:         REAL;     // Zähler für Verzögerung Sonnenschutz
  ResetSonne:       REAL;     // Zähler für Verzögerung Sonnenschutz wieder hochfahren
  Auto:             BOOL;     // Aktuell Automatikbetrieb
  Sonnenschutz:     BOOL;     // Aktuell Sonnenschutz
  ProzAuf:          REAL;     // Soviel Prozent sind in 0,5 Sekunden gefahren in Auf
  ProzAb:           REAL;     // Soviel Prozent sind in 0,5 Sekunden gefahren in Ab
  SollZt:           REAL;     // SollZeit für aktuelle Fahrt in [Sek.]
  SollSt:           REAL;     // Sollstellung in [%]
  SonneAb:          BOOL;     // Freigabe Sonnenschutz
  SonneAuf:         BOOL;     // Freigabe Sonnenschutz wieder hoch
END_VAR
VAR_OUTPUT
  AusgangAuf:       BOOL;     // Ausgang für Auf
  AusgangAb:        BOOL;     // Ausgang für Ab
  HandAuf:          BOOL;     // Aktuell Fährt per Hand Auf
  HandAb:           BOOL;     // Aktuell Fährt per Hand Ab
  InnenAufheizen:   BOOL;     // Aktuell Innen Aufheizen
  Sichtschutz:      BOOL;     // Aktuell Sichtschutz
  ZwangAuf:         BOOL;     // Aktuell Zwang Auf
  ZwangZu:          BOOL;     // Aktuell Zwnag Zu
  Gesperrt:         BOOL;     // Aktuell gesperrt
END_VAR
 
// ****************************************************************************
// Reset
// ****************************************************************************
IF ResetAll=true THEN
  AusgangAuf:=false;
  AusgangAb:=false;
  IstZtAuf:=0;
  IstZtAb:=0;
  SollSt:=0;
END_IF;
// ****************************************************************************
// Rückstellen in Automatikbetrieb
// Bei Hand- oder Winterbetrieb Automatikfunktionen deaktivieren
// Rückstellen automatisch oder per Hand (ResetAutoATV)
// ****************************************************************************
IF ResetAutoEN=true AND ResetAutoATV=true AND AutoATV=true THEN
  Auto:=true;
ELSIF TastAuf=true OR TastAb=true OR AutoATV=false THEN
  Auto:=false;
  Sonnenschutz:=false; 
END_IF;  
// ****************************************************************************
// Fahren per Handbetrieb in Aufrichtung TASTBETRIEB
// ****************************************************************************
IF Auto=false AND TastAuf=true THEN
  HandAuf:=true;
  ProzAuf:=50/LZAuf;
  AusgangAuf:=true;
  IF Takt=true THEN
    IstSt:=ROUND(IstSt-ProzAuf);
    IF IstSt<=0 THEN
      IstSt:=0;
    END_IF;    
  END_IF; 
ELSE
  AusgangAuf:=false;
  HandAuf:=false;
END_IF;
// ****************************************************************************
// Fahren per Handbetrieb in Abrichtung TASTBETRIEB
// ****************************************************************************
IF Auto=false AND TastAb=true THEN
  HandAb:=true;
  ProzAuf:=50/LZAb;
  AusgangAb:=true;
  IF Takt=true THEN
    IstSt:=ROUND(IstSt+ProzAuf);
    IF IstSt>=100 THEN
      IstSt:=100;
    END_IF;  
  END_IF; 
ELSE
  AusgangAb:=false;
  HandAb:=false;
END_IF;
// ****************************************************************************
// Niedrigste Priorität: Sonnenschutz
// ****************************************************************************
// Verzögerung bis zum Beschatten
IF Auto=true AND SonneEN=true AND LuxIst>20000 AND LuxIst>LuxSoll THEN
  ResetSonne:=0;
  IF Takt=true THEN
      SetSonne:=SetSonne+0.5;
  END_IF;
  IF SetSonne>=ROUND(SonneAbNach*60) THEN
    SonneAb:=true;
    SonneAuf:=false; 
    SetSonne:=0; 
  END_IF; 
END_IF;  
// Verzögerung bis zum Wiederhochfahren
IF Auto=true AND SonneEN=true AND LuxIst<LuxSoll THEN
  SetSonne:=0;
  IF Takt=true THEN
      ResetSonne:=ResetSonne+0.5;
  END_IF;
  IF ResetSonne>=ROUND(SonneAufNach*60) THEN
    SonneAuf:=true;
    SonneAb:=false;
    ResetSonne:=0;
  END_IF;  
END_IF;  
IF Auto=true AND SonneEN=true AND SonneAb=true THEN
  Sonnenschutz:=true;
  SollSt:=SonneSW;
ELSIF Auto=true AND SonneEN=true AND SonneAuf=true THEN
  SollSt:=0; 
  Sonnenschutz:=false; 
END_IF; 
IF Auto=true AND SonneEN=false THEN
  SollSt:=0;
  Sonnenschutz:=false;
END_IF;  
// ****************************************************************************
// Innen aufheizen
// ****************************************************************************
IF Auto=true AND InnenHeizEN=true AND InTempIst<=InTempSoll THEN
  InnenAufheizen:=true;
  Sonnenschutz:=false;
  SollSt:=0;
ELSE
  InnenAufheizen:=false;  
END_IF;
// ****************************************************************************
// Sichtschutz
// ****************************************************************************
IF Auto=true AND SichtEN=true AND SichtATV=true THEN
  Sichtschutz:=true;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=SichtSW;
ELSE
  Sichtschutz:=false;
END_IF;
// ****************************************************************************
// Zwangsschließen
// ****************************************************************************
IF Auto=true AND ZwangZuEN=true AND ZwangZuATV=true THEN
  ZwangZu:=true;
  Sichtschutz:=false;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=100;
ELSE
  ZwangZu:=false;
END_IF;
// ****************************************************************************
// Zwangsöffnen
// ****************************************************************************
IF Auto=true AND ZwangAufEN=true AND ZwangAufATV=true THEN
  ZwangAuf:=true;
  ZwangZu:=false;
  Sichtschutz:=false;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=0;
ELSE
  ZwangAuf:=false;  
END_IF;
// ****************************************************************************
// Sperren wegen niedriger Aussentemperatur
// ****************************************************************************
IF Auto=true AND AussenTempEN=true AND AuTempIst<=AuTempSoll THEN
  Gesperrt:=true;
  ZwangAuf:=false;
  ZwangZu:=false;
  Sichtschutz:=false;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=0;
ELSE   
  Gesperrt:=false;
  //SollSt:=0;
END_IF;
// ****************************************************************************
// Bei Automatikbetrieb gewünschte Stellung anfahren
// ****************************************************************************
IF Auto=true THEN
  // Ausgang auf gewünschten Sollwert fahren
 
  // Sollstellung erreicht
  IF AusgangAuf=true AND IstSt<=SollSt OR AusgangAb=true AND IstSt>=SollSt THEN
    AusgangAuf:=false;  
    AusgangAb:=false;
    IstZtAuf:=0.0;
    IstZtAb:=0.0;
    IstSt:=SollSt;
  END_IF;
 
  // Auffahren
  IF SollSt<IstSt AND AusgangAb=false THEN
  // Laufzeit für Auf festlegen
    SollZt:=LZAuf/100*(IstSt-SollSt);  
  // Wieviel % entspricht 0.5 Sekunden?
    ProzAuf:=50/LZAuf;
    AusgangAuf:=true;
    IF Takt=true THEN
      IstZtAuf:=IstZtAuf+0.5;
      IstSt:=IstSt-ProzAuf;
    END_IF; 
  END_IF;
  // Abfahren
  IF SollSt>IstSt  AND AusgangAuf=false THEN
  // Laufzeit für Ab festlegen
    SollZt:=LZAb/100*(SollSt-IstSt);  
  // Wieviel % entspricht 0.5 Sekunden?
    ProzAb:=50/LZAb;
    AusgangAb:=true;
    IF Takt=true THEN
      IstZtAb:=IstZtAb+0.5;
      IstSt:=IstSt+ProzAb;
    END_IF; 
  END_IF; 
END_IF;  
 
 
  ;
END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Erstmal vielen Dank für euere Hilfe! Werde es morgen mal angehen.
Danke auch an zotos wegen dem Tipp mit der Lesbarkeit. Hier also noch mal alles in lesbarer Form:

Code:
// Funktion für Jalousieantriebe
FUNCTION FC12 : VOID
VAR_INPUT
  LZAuf:            REAL;     // Laufzeit für 100% Auf
  LZAb:             REAL;     // Laufzeit für 100% Ab
  Takt:             BOOL;     // Impuls pro 0,5 Sekunden
  // Automatikfreigabe
  AutoATV:          BOOL;     // Generelle Freigabe der Automatikfunktionen
  // Sperren bei niedriger Aussentemperatur
  AussentempEN:     BOOL;     // Sperren bei niedriger Aussentemperatur ENABLE
  AuTempSoll:       REAL;     // Sperren ab Aussentemperatur [°C]
  AuTempIst:        REAL;     // Aktuelle Aussentemperatur [°C]
  // Zwangsöffnen
  ZwangAufEN:       BOOL;     // Zwangsöffnen (Einbruch..) ENABLE
  ZwangAufATV:      BOOL;     // Zwangsöffnen (Einbruch..) AKTIV
  // Zwangsschließen
  ZwangZuEN:        BOOL;     // Zwangsschließen ENABLE
  ZwangZuATV:       BOOL;     // Zwangsschließen AKTIV
  // Sichtschutz
  SichtEN:          BOOL;     // Sichtschutz ENABLE
  SichtATV:         BOOL;     // Sichtschutz AKTIV
  SichtSW:          REAL;     // Sollstellung für Sichtschutz [%] 
  // Innen aufheizen 
  InnenheizEN:      BOOL;     // Innen Aufheizen ENABLE
  InTempSoll:       REAL;     // Innen Aufheizen bis Temperatur [°C]
  InTempIst:        REAL;     // Aktuelle Temperatur [°C]
  // Sonnenschutz
  SonneEN:          BOOL;     // Sonnenschutz ENABLE
  LuxSoll:          REAL;     // Sonnenschutz ab Helligkeit [Lux]
  LuxIst:           REAL;     // Aktuelle Helligkeit [Lux]
  SonneSW:          REAL;     // Sollstellung für Sonnenschutz [%] 
  SonneAbNach:      INT;      // Sonnenschutz Ab nach einer Verzögerungszeit [Sek.]
  SonneAufNach:     INT;      // Sonnenschutz Auf nach einer Verzögerungszeit [Sek.]
  // Handbetrieb
  TastAuf:          BOOL;     // Taster für Hand Auf
  TastAb:           BOOL;     // Taster für Hand Ab
  // Rücksetzen in Automatikbetrieb
  ResetAutoEN:      BOOL;     // Rücksetzen in Automatikbetrieb ENABLE
  ResetAutoATV:     BOOL;     // Rücksetzen in Automatikbetrieb AKTIV 
  // Reset
  ResetAll:         BOOL;     // Reset
END_VAR
VAR_IN_OUT
  IstSt:            REAL;     // Iststellung in [%]
  IstZtAuf:         REAL;     // Istzeit (aktuelle Fahrt) in [Sek.] Auf
  IstZtAb:          REAL;     // Istzeit (aktuelle Fahrt) in [Sek.] Ab
  SetSonne:         REAL;     // Zähler für Verzögerung Sonnenschutz
  ResetSonne:       REAL;     // Zähler für Verzögerung Sonnenschutz wieder hochfahren
  Auto:             BOOL;     // Aktuell Automatikbetrieb
  Sonnenschutz:     BOOL;     // Aktuell Sonnenschutz
  ProzAuf:          REAL;     // Soviel Prozent sind in 0,5 Sekunden gefahren in Auf
  ProzAb:           REAL;     // Soviel Prozent sind in 0,5 Sekunden gefahren in Ab
  SollZt:           REAL;     // SollZeit für aktuelle Fahrt in [Sek.]
  SollSt:           REAL;     // Sollstellung in [%]
  SonneAb:          BOOL;     // Freigabe Sonnenschutz
  SonneAuf:         BOOL;     // Freigabe Sonnenschutz wieder hoch
END_VAR
VAR_OUTPUT
  AusgangAuf:       BOOL;     // Ausgang für Auf
  AusgangAb:        BOOL;     // Ausgang für Ab
  HandAuf:          BOOL;     // Aktuell Fährt per Hand Auf
  HandAb:           BOOL;     // Aktuell Fährt per Hand Ab
  InnenAufheizen:   BOOL;     // Aktuell Innen Aufheizen
  Sichtschutz:      BOOL;     // Aktuell Sichtschutz
  ZwangAuf:         BOOL;     // Aktuell Zwang Auf
  ZwangZu:          BOOL;     // Aktuell Zwnag Zu
  Gesperrt:         BOOL;     // Aktuell gesperrt
END_VAR
 
// ****************************************************************************
// Reset
// ****************************************************************************
IF ResetAll=true THEN
  AusgangAuf:=false;
  AusgangAb:=false;
  IstZtAuf:=0;
  IstZtAb:=0;
  SollSt:=0;
END_IF;
// ****************************************************************************
// Rückstellen in Automatikbetrieb
// Bei Hand- oder Winterbetrieb Automatikfunktionen deaktivieren
// Rückstellen automatisch oder per Hand (ResetAutoATV)
// ****************************************************************************
IF ResetAutoEN=true AND ResetAutoATV=true AND AutoATV=true THEN
  Auto:=true;
ELSIF TastAuf=true OR TastAb=true OR AutoATV=false THEN
  Auto:=false;
  Sonnenschutz:=false; 
END_IF;  
// ****************************************************************************
// Fahren per Handbetrieb in Aufrichtung TASTBETRIEB
// ****************************************************************************
IF Auto=false AND TastAuf=true THEN
  HandAuf:=true;
  ProzAuf:=50/LZAuf;
  AusgangAuf:=true;
  IF Takt=true THEN
    IstSt:=ROUND(IstSt-ProzAuf);
    IF IstSt<=0 THEN
      IstSt:=0;
    END_IF;    
  END_IF; 
ELSE
  AusgangAuf:=false;
  HandAuf:=false;
END_IF;
// ****************************************************************************
// Fahren per Handbetrieb in Abrichtung TASTBETRIEB
// ****************************************************************************
IF Auto=false AND TastAb=true THEN
  HandAb:=true;
  ProzAuf:=50/LZAb;
  AusgangAb:=true;
  IF Takt=true THEN
    IstSt:=ROUND(IstSt+ProzAuf);
    IF IstSt>=100 THEN
      IstSt:=100;
    END_IF;  
  END_IF; 
ELSE
  AusgangAb:=false;
  HandAb:=false;
END_IF;
// ****************************************************************************
// Niedrigste Priorität: Sonnenschutz
// ****************************************************************************
// Verzögerung bis zum Beschatten
IF Auto=true AND SonneEN=true AND LuxIst>20000 AND LuxIst>LuxSoll THEN
  ResetSonne:=0;
  IF Takt=true THEN
      SetSonne:=SetSonne+0.5;
  END_IF;
  IF SetSonne>=ROUND(SonneAbNach*60) THEN
    SonneAb:=true;
    SonneAuf:=false; 
    SetSonne:=0; 
  END_IF; 
END_IF;  
// Verzögerung bis zum Wiederhochfahren
IF Auto=true AND SonneEN=true AND LuxIst<LuxSoll THEN
  SetSonne:=0;
  IF Takt=true THEN
      ResetSonne:=ResetSonne+0.5;
  END_IF;
  IF ResetSonne>=ROUND(SonneAufNach*60) THEN
    SonneAuf:=true;
    SonneAb:=false;
    ResetSonne:=0;
  END_IF;  
END_IF;  
IF Auto=true AND SonneEN=true AND SonneAb=true THEN
  Sonnenschutz:=true;
  SollSt:=SonneSW;
ELSIF Auto=true AND SonneEN=true AND SonneAuf=true THEN
  SollSt:=0; 
  Sonnenschutz:=false; 
END_IF; 
IF Auto=true AND SonneEN=false THEN
  SollSt:=0;
  Sonnenschutz:=false;
END_IF;  
// ****************************************************************************
// Innen aufheizen
// ****************************************************************************
IF Auto=true AND InnenHeizEN=true AND InTempIst<=InTempSoll THEN
  InnenAufheizen:=true;
  Sonnenschutz:=false;
  SollSt:=0;
ELSE
  InnenAufheizen:=false;  
END_IF;
// ****************************************************************************
// Sichtschutz
// ****************************************************************************
IF Auto=true AND SichtEN=true AND SichtATV=true THEN
  Sichtschutz:=true;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=SichtSW;
ELSE
  Sichtschutz:=false;
END_IF;
// ****************************************************************************
// Zwangsschließen
// ****************************************************************************
IF Auto=true AND ZwangZuEN=true AND ZwangZuATV=true THEN
  ZwangZu:=true;
  Sichtschutz:=false;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=100;
ELSE
  ZwangZu:=false;
END_IF;
// ****************************************************************************
// Zwangsöffnen
// ****************************************************************************
IF Auto=true AND ZwangAufEN=true AND ZwangAufATV=true THEN
  ZwangAuf:=true;
  ZwangZu:=false;
  Sichtschutz:=false;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=0;
ELSE
  ZwangAuf:=false;  
END_IF;
// ****************************************************************************
// Sperren wegen niedriger Aussentemperatur
// ****************************************************************************
IF Auto=true AND AussenTempEN=true AND AuTempIst<=AuTempSoll THEN
  Gesperrt:=true;
  ZwangAuf:=false;
  ZwangZu:=false;
  Sichtschutz:=false;
  InnenAufheizen:=false;
  Sonnenschutz:=false;
  SollSt:=0;
ELSE   
  Gesperrt:=false;
  //SollSt:=0;
END_IF;
// ****************************************************************************
// Bei Automatikbetrieb gewünschte Stellung anfahren
// ****************************************************************************
IF Auto=true THEN
  // Ausgang auf gewünschten Sollwert fahren
 
  // Sollstellung erreicht
  IF AusgangAuf=true AND IstSt<=SollSt OR AusgangAb=true AND IstSt>=SollSt THEN
    AusgangAuf:=false;  
    AusgangAb:=false;
    IstZtAuf:=0.0;
    IstZtAb:=0.0;
    IstSt:=SollSt;
  END_IF;
 
  // Auffahren
  IF SollSt<IstSt AND AusgangAb=false THEN
  // Laufzeit für Auf festlegen
    SollZt:=LZAuf/100*(IstSt-SollSt);  
  // Wieviel % entspricht 0.5 Sekunden?
    ProzAuf:=50/LZAuf;
    AusgangAuf:=true;
    IF Takt=true THEN
      IstZtAuf:=IstZtAuf+0.5;
      IstSt:=IstSt-ProzAuf;
    END_IF; 
  END_IF;
  // Abfahren
  IF SollSt>IstSt  AND AusgangAuf=false THEN
  // Laufzeit für Ab festlegen
    SollZt:=LZAb/100*(SollSt-IstSt);  
  // Wieviel % entspricht 0.5 Sekunden?
    ProzAb:=50/LZAb;
    AusgangAb:=true;
    IF Takt=true THEN
      IstZtAb:=IstZtAb+0.5;
      IstSt:=IstSt+ProzAb;
    END_IF; 
  END_IF; 
END_IF;  
 
 
  ;
END_FUNCTION


:) für mich sieht das aus wie das kursbuch der db, habe ich auch nicht verstanden.

Frank
 
wieder OFF_Topic

:) vermutlich mei gudster

OFF_TOPIC_ENDE

Frank

PS kommt nicht wieder vor, hoffe ich
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
nur so'n paar Vorschläge

1. Bei den vielen IN-OUT Variablen würde ich ein FB statt ein FC verwenden.

2. Mal Überlegen, ob es wirklich soviele Variablen an den Schnittstellen braucht, oder ob man auch mit weniger auskommt.

3. Evt. mehrere kleine FB/FCs aus dem Problem machen, dann findest du eher den Fehler.
 
1. Bei den vielen IN-OUT Variablen würde ich ein FB statt ein FC verwenden.

2. Mal Überlegen, ob es wirklich soviele Variablen an den Schnittstellen braucht, oder ob man auch mit weniger auskommt.

3. Evt. mehrere kleine FB/FCs aus dem Problem machen, dann findest du eher den Fehler.


Ich zitiere mich mal selbst:


Der Nachteil eines FC ist, das IMMER alle Eingänge beschaltet werden müssen - deshalb empfehle ich das als MultiinstanzFB zu machen.


Das sollte nochmal ein Denkanstoss sein.
 
Habe mich mal von eueren Anregungen inspirieren lassen :)
Der (letzte Teil) des Codes sieht nun folgendermaßen aus:

Code:
// ****************************************************************************
// Bei Automatikbetrieb gewünschte Stellung anfahren
// ****************************************************************************
IF Auto=true THEN
  // Ausgang auf gewünschten Sollwert fahren
 
  // Sollstellung erreicht
  IF IstSt=SollSt THEN
    AusgangAuf:=false;  
    AusgangAb:=false;
    IstZtAuf:=0.0;
    IstZtAb:=0.0;
  END_IF;
 
  // Auffahren
  IF SollSt<IstSt AND AusgangAb=false THEN
  // Laufzeit für Auf festlegen
    SollZt:=LZAuf/100*(IstSt-SollSt);  
  // Wieviel % entspricht 0.5 Sekunden?
    ProzAuf:=50/LZAuf;
    AusgangAuf:=true;
    IF Takt=true THEN
      IstZtAuf:=IstZtAuf+0.5;
      IstSt:=IstSt-ProzAuf;
      IF IstSt<=SollSt THEN
        IstSt:=SollSt;
      END_IF;
    END_IF; 
  END_IF;
  // Abfahren
  IF SollSt>IstSt  AND AusgangAuf=false THEN
  // Laufzeit für Ab festlegen
    SollZt:=LZAb/100*(SollSt-IstSt);  
  // Wieviel % entspricht 0.5 Sekunden?
    ProzAb:=50/LZAb;
    AusgangAb:=true;
    IF Takt=true THEN
      IstZtAb:=IstZtAb+0.5;
      IstSt:=IstSt+ProzAb;
      IF IstSt>=SollSt THEN
        IstSt:=SollSt;
      END_IF;
    END_IF; 
  END_IF; 
END_IF;

Im Grunde habe ich nur die Sollpos.=Istpos. - Erkennung etwas umgebaut. Das Ganze scheint nun zu funzen.
FB wollte ich nicht nehmen, da ich den Aufruf 16x machen muss und die Variablen einfacher editiert werden können auf diese Weise. Wenn möglich, vermeide ich immer FBs, weil ich dann nicht im Instanz-DB rumschreiben und -lesen muss. Lieber baue ich mir meinen DB so wie ich ihn brauche.

Also, nochmals danke für euere Hilfe (hoffentlich tuts das Teil nun wirklich...)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Im Grunde habe ich nur die Sollpos.=Istpos. - Erkennung etwas umgebaut.

Wie gesagt, meiner Meinung liegt der Fehler im ELSE-Zweig des Handbetreibs. Die Stopp-Auswertung fand ich vorher besser, aber diese wurde vorher nicht durchlaufen. Nun gut, jetzt wird's zumindest ausgeführt. Ob sich diese Zeitzuweisungen auswirken habe ich mir nicht angesehen.

Ich hätte im vorigen Code mindestens folgendes geändert:

Code:
[FONT="Courier New"]// ************************************************** **************************
// TASTBETRIEB
// ************************************************** **************************
IF Auto=false THEN
  // *** Aufwaerts ********************
  IF TastAuf=true THEN
    HandAuf:=true;
    ProzAuf:=50/LZAuf;
    AusgangAuf:=true;
    IF Takt=true THEN
      IstSt:=ROUND(IstSt-ProzAuf);
      IF IstSt<=0 THEN
        IstSt:=0;
      END_IF; 
    END_IF; 
  ELSE
    AusgangAuf:=false;
    HandAuf:=false;
  END_IF,
  // *** Abwaerts *********************
  IF TastAb=true THEN
    HandAb:=true;
    ProzAuf:=50/LZAb;
    AusgangAb:=true;
    IF Takt=true THEN
      IstSt:=ROUND(IstSt+ProzAuf);
      IF IstSt>=100 THEN
        IstSt:=100;
      END_IF; 
    END_IF; 
  ELSE
    AusgangAb:=false;
    HandAb:=false;
  END_IF;
ELSE
  // *** Rückmeldungen in Auto löschen *
  HandAuf:=false;
  HandAb:=false;
END_IF; // Auto=false

// *** Sollstellung erreicht **********
IF AusgangAuf=true AND IstSt<=SollSt OR
   AusgangAb=true  AND IstSt>=SollSt 
THEN
  AusgangAuf:=false; 
  AusgangAb:=false;
  IstZtAuf:=0.0;
  IstZtAb:=0.0;
  IstSt:=SollSt; // Statt der Zuweisung würde ich in
                 // INPOS-Fenster um SollSt legen
END_IF;
[/FONT]
 
Zurück
Oben