Step 7 SCL Problem (Anfänger)

chomp

Level-1
Beiträge
10
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich bin neu hier im Forum und habe ein Problem mit einem SCL-Baustein. Ich arbeite mit dem Simatic Manager V5.4.
Ich arbeite an der Automatisierung meines Hauses und konkret an einem FB für die Rollladensteuerung.
Der Besagte FB (siehe Anhang) soll die aktuelle Position des Rollladens selbständig berechnen. Mein Konzept ist (ähnlich wie OSCAT) so aufgebaut das an einem FB ein Eingangssignal wie z.B. I_Close nur für einen Zyklus anliegen darf, dies wird aber von den vorgeschalteten, sich bereits länger im Einsatz befindlichen FBs, sichergestellt.
Soweit sieht das mit meinem FB auch ganz gut aus nur wenn ich die Bewegung stoppe, egal ob durch Erreichen der Zielposition oder externes Stop (I_Stop oder neuer Move Befehl)). Fängt er an die Bewegung umzukehren und fährt wieder hoch!
Ich habe das schon etliche Male durchgespielt I_Close (fährt runter) ... warten ... I_Stop. Jetzt beginnt der Baustein den Q_Up zu schalten und berechnet auch die Rückfahrt wieder.
Ich habe das ganze schon dutzende Male im Kopf durchgespielt komme aber nicht auf den Fehler und kann mir nicht erklären warum er plötzlich den Q_Up schaltet.
Bin für jeden Tipp dankbar der mir hilft das Problem ggf. weiter einzugrenzen, da ich keinen Ansatz mehr habe.

Dies ist mein allererstes SCL Programm, daher bin ich generell für alle Tipps dankbar, was sollte ich lassen, was evtl. besser / eleganter machen.

Schöne Grüße
chomp
 

Anhänge

  • blind_scl.txt
    6,4 KB · Aufrufe: 16
Hier noch der Code:
Code:
FUNCTION_BLOCK Blind

VAR_INPUT
  I_Open: BOOL;
  I_Close: BOOL;
  I_Stop: BOOL;    
  I_TriTrig: BOOL;
  I_MoveUp: BOOL;
  I_MoveDown: BOOL;
  I_Reference: BOOL;
  I_Value: REAL;
  I_PosUp : REAL := 0.0;
  I_PosDown: REAL := 100.0;
  I_TimeUp: TIME := T#90s;
  I_TimeDown: TIME := T#90s;
END_VAR

VAR_OUTPUT
  Q_Up : BOOL;
  Q_Down : BOOL;
  Q_Moving : BOOL;
  Q_Reference : BOOL;
  Q_Position : REAL;
  Q_TimeToDest:TIME;
END_VAR

VAR_TEMP
  T_IsMovingCmd : BOOL;
  T_Stop : BOOL;
  T_LockElapsed : BOOL;
  T_CurValue : REAL;
  T_Moved : TIME;
  T_CalcBaseTime : TIME;
END_VAR

CONST
    OFFSET_TIME := T#1S;
    ZERO_T := T#0S;
    LOCK_TIME := T#50Ms;
    UP := 0;
    DOWN := 1;
END_CONST

VAR
  IsReference : BOOL := false;
  ReferenceDone : BOOL := false;
  LastDirection : INT := UP;
  StartValue : REAL := 0.0; 
  GivenValue : REAL := 0.0;
  TimeStart : TIME := ZERO_T; 
  TimeToMove : TIME := ZERO_T;
  StartLock : TIME := ZERO_T;
END_VAR



LABEL
    M1, End;
END_LABEL


BEGIN

//init Temp vars
T_Stop := false;
T_CurValue := Q_Position;
T_CalcBaseTime := ZERO_T;
T_Moved := ZERO_T;
T_LockElapsed := false;
T_IsMovingCmd := (  I_Open OR  I_Close OR I_TriTrig OR I_MoveUp OR I_MoveDown OR I_Reference);

//check lock
IF NOT(StartLock = ZERO_T) THEN;
    IsTimeElapsed(T_Start :=  StartLock
                  ,T_Time2Go :=  LOCK_TIME
                  ,Q := T_LockElapsed
                  );
  
  IF(T_LockElapsed) 
      THEN StartLock := ZERO_T;
      ELSE GOTO End;
  END_IF;
END_IF;

// Stop on new Command 
IF(T_IsMovingCmd AND Q_Moving) THEN;
    T_Stop := true;
    GOTO M1;
END_IF;

IF I_Open THEN;
   Q_Up := true;
   Q_Down := false;
   GivenValue := I_PosUp;
   StartValue := Q_Position;
   TimeToMove := DINT_TO_TIME(REAL_TO_DINT( (Q_Position * DINT_TO_REAL(TIME_TO_DINT(I_TimeUp))) / 100 )) + OFFSET_TIME;
   TimeStart:= TIME_TCK();
        
ELSIF I_Close THEN;
   Q_Up := false; 
   Q_Down := true;
   GivenValue := I_PosDown;
   StartValue := Q_Position;
   TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((100.0 - Q_Position) * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown))  ) / 100)) + OFFSET_TIME;
   TimeStart:= TIME_TCK();
        
ELSIF I_TriTrig THEN;
    IF( LastDirection = UP) THEN;
         Q_Up := false; 
         Q_Down := true;
         GivenValue := I_PosDown;
         StartValue := Q_Position;
         TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((100.0 - Q_Position) * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown))  ) / 100)) + OFFSET_TIME;
         TimeStart:= TIME_TCK();
    ELSIF (LastDirection = DOWN) THEN;
         Q_Up := true;
         Q_Down := false;
         GivenValue := I_PosUp;
         StartValue := Q_Position;
         TimeToMove := DINT_TO_TIME(REAL_TO_DINT( (Q_Position * DINT_TO_REAL(TIME_TO_DINT(I_TimeUp))) / 100 )) + OFFSET_TIME;
         TimeStart:= TIME_TCK();
    END_IF;
           
        
ELSIF I_MoveUp THEN;
   IF NOT(TimeStart = ZERO_T) THEN;
      Q_Up := true;
      Q_Down := false;
      TimeStart := TIME_TCK();
      StartValue := Q_Position;
      TimeToMove := ZERO_T;
   END_IF;
          
ELSIF I_MoveDown THEN;
   IF NOT(TimeStart = ZERO_T) THEN;
      Q_Up := false;
      Q_Down := true;
      TimeStart := TIME_TCK();
      StartValue := Q_Position;
      TimeToMove := ZERO_T;
   END_IF;
        
ELSIF I_Stop THEN;
      T_Stop := true;
    
ELSIF I_Reference THEN;
    Q_Up := true; 
    Q_Down := false;
    GivenValue := I_PosDown;
    StartValue := Q_Position;
    TimeToMove := I_TimeUp + OFFSET_TIME;
    TimeStart:= TIME_TCK();
    IsReference := true;

ELSIF NOT(I_Value = GivenValue) THEN;
    IF NOT (Q_Moving) THEN;
        StartValue := Q_Position;
        GivenValue := I_Value;
        TimeStart := TIME_TCK();
        IF (GivenValue > Q_Position) THEN;
            Q_Up := false;
            Q_Down := true;
            TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((100.0 - (GivenValue - Q_Position)) * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown)) ) / 100));
        ELSE;
            Q_Up := true;
            Q_Down := false;
            TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((Q_Position - GivenValue) * DINT_TO_REAL(TIME_TO_DINT(I_TimeUp))) / 100 ));
        END_IF;
    END_IF;

ELSIF (IsReference AND ReferenceDone) THEN;
    IsReference := false;
    GivenValue := StartValue;
    StartValue := Q_Position;
    TimeStart := TIME_TCK();
    IF (GivenValue > Q_Position) THEN;
        Q_Up := false;
        Q_Down := true;
        TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((100.0 - (GivenValue - Q_Position)) * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown)) ) / 100));
    ELSE;
        Q_Up := true;
        Q_Down := false;
        TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((Q_Position - GivenValue) * DINT_TO_REAL(TIME_TO_DINT(I_TimeUp))) / 100 ));
    END_IF;


    
ELSIF NOT(Q_Moving) THEN;
    //Nothing todo;
    RETURN;
    
END_IF;

// ----- End Of Inputanalysis --------------------------------------------------//

M1: ;

//Calculate Position on Moving
IF(Q_Moving) THEN;
    T_Moved := (TIME_TCK() - TimeStart);
    
    IF(TimeToMove > ZERO_T) THEN;    
        T_CalcBaseTime := TimeToMove;
    ELSIF (Q_Moving) THEN;
        TimeToMove := T_Moved;
        IF (I_MoveUp) THEN;
            T_CalcBaseTime := I_TimeUp;
        ELSIF(I_MoveDown) THEN;
            T_CalcBaseTime := I_TimeDown;
        END_IF;    
    END_IF;
    
    T_CurValue := 100 * (DINT_TO_REAL(TIME_TO_DINT(T_Moved)) / DINT_TO_REAL(TIME_TO_DINT(T_CalcBaseTime))); 
    
    IF Q_Up THEN 
        T_CurValue := (StartValue - T_CurValue);
    ELSE;
        T_CurValue := (StartValue + T_CurValue);
    END_IF;
        
    IF(T_Moved >= TimeToMove) THEN;
        T_Stop := true;
    END_IF;
END_IF;


IF(T_Stop) THEN;
    IF(Q_Up) THEN;
        LastDirection := UP;
    ELSE;
        LastDirection := DOWN;
    END_IF;
        
    Q_Up := false;
    Q_Down := false;
    T_Moved := ZERO_T;
    TimeToMove := ZERO_T;
    TimeStart := ZERO_T;
    StartLock := TIME_TCK();
    
    IF(IsReference) THEN;
        ReferenceDone := true;
    END_IF;
END_IF;
  
IF(T_CurValue <= 0) THEN;
    Q_Position := 0.0;
ELSIF(T_CurValue > 100) THEN;
    Q_Position := 100.0;
ELSE;
    Q_Position := T_CurValue;
END_IF;

Q_Moving := (Q_Up OR Q_Down);
Q_TimeToDest := (TimeToMove - T_Moved);


END: ; //Function End

END_FUNCTION_BLOCK

Edit: Was mir auch nicht gefällt sind die Codedoppelungen. In c würde ich hier eine Funktion schreiben, aber in SCL habe ich leider keine Idee


Schöne Grüße
chomp
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Fixed

Ok, nach noch mehr Durchläufen und Gehirnschmalz gelöst! Der Vollständigkeit halber:

Code:
FUNCTION_BLOCK Blind

VAR_INPUT
  I_Open: BOOL;
  I_Close: BOOL;
  I_Stop: BOOL;
  I_TriTrig: BOOL;
  I_MoveUp: BOOL;
  I_MoveDown: BOOL;
  I_Reference: BOOL;
  I_Value: REAL;
  I_PosUp : REAL := 0.0;
  I_PosDown: REAL := 100.0;
  I_TimeUp: TIME := T#90s;
  I_TimeDown: TIME := T#90s;
END_VAR

VAR_OUTPUT
  Q_Up : BOOL;
  Q_Down : BOOL;
  Q_Moving : BOOL;
  Q_Reference : BOOL;
  Q_Position : REAL;
  Q_TimeToDest:TIME;
END_VAR

VAR_TEMP
  T_IsMovingCmd : BOOL;
  T_Stop : BOOL;
  T_LockElapsed : BOOL;
  T_CurValue : REAL;
  T_Moved : TIME;
  T_CalcBaseTime : TIME;
END_VAR

CONST
    OFFSET_TIME := T#1S;
    ZERO_T := T#0S;
    LOCK_TIME := T#50Ms;
    UP := 0;
    DOWN := 1;
END_CONST

VAR
  IsReference : BOOL := false;
  ReferenceDone : BOOL := false;
  LastDirection : INT := UP;
  StartValue : REAL := 0.0;
  GivenValue : REAL := 0.0;
  TimeStart : TIME := ZERO_T;
  TimeToMove : TIME := ZERO_T;
  StartLock : TIME := ZERO_T;
END_VAR

LABEL
    M1, End;
END_LABEL


BEGIN

//init Temp vars
T_Stop := false;
T_CurValue := Q_Position;
T_CalcBaseTime := ZERO_T;
T_Moved := ZERO_T;
T_LockElapsed := false;
T_IsMovingCmd := (  I_Open OR  I_Close OR I_TriTrig OR I_MoveUp OR I_MoveDown OR I_Reference);

//check lock
IF NOT(StartLock = ZERO_T) THEN;
    IsTimeElapsed(T_Start :=  StartLock
                  ,T_Time2Go :=  LOCK_TIME
                  ,Q := T_LockElapsed
                  );

  IF(T_LockElapsed)
      THEN StartLock := ZERO_T;
      ELSE GOTO End;
  END_IF;
END_IF;

// Stop on new Command
IF(T_IsMovingCmd AND Q_Moving) THEN;
    T_Stop := true;
    GOTO M1;
END_IF;

IF I_Open THEN;
   Q_Up := true;
   Q_Down := false;
   GivenValue := I_PosUp;
   StartValue := Q_Position;
   TimeToMove := DINT_TO_TIME(REAL_TO_DINT( (Q_Position * DINT_TO_REAL(TIME_TO_DINT(I_TimeUp))) / 100 )) + OFFSET_TIME;
   TimeStart:= TIME_TCK();

ELSIF I_Close THEN;
   Q_Up := false;
   Q_Down := true;
   GivenValue := I_PosDown;
   StartValue := Q_Position;
   TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((100.0 - Q_Position) * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown))  ) / 100)) + OFFSET_TIME;
   TimeStart:= TIME_TCK();

ELSIF I_TriTrig THEN;
    IF( LastDirection = UP) THEN;
         Q_Up := false;
         Q_Down := true;
         GivenValue := I_PosDown;
         StartValue := Q_Position;
         TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((100.0 - Q_Position) * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown))  ) / 100)) + OFFSET_TIME;
         TimeStart:= TIME_TCK();
    ELSIF (LastDirection = DOWN) THEN;
         Q_Up := true;
         Q_Down := false;
         GivenValue := I_PosUp;
         StartValue := Q_Position;
         TimeToMove := DINT_TO_TIME(REAL_TO_DINT( (Q_Position * DINT_TO_REAL(TIME_TO_DINT(I_TimeUp))) / 100 )) + OFFSET_TIME;
         TimeStart:= TIME_TCK();
    END_IF;


ELSIF I_MoveUp THEN;
   IF (TimeStart = ZERO_T) THEN;
      Q_Up := true;
      Q_Down := false;
      TimeStart := TIME_TCK();
      StartValue := Q_Position;
      TimeToMove := ZERO_T;
   END_IF;

ELSIF I_MoveDown THEN;
   IF (TimeStart = ZERO_T) THEN;
      Q_Up := false;
      Q_Down := true;
      TimeStart := TIME_TCK();
      StartValue := Q_Position;
      TimeToMove := ZERO_T;
   END_IF;

ELSIF I_Stop THEN;
      T_Stop := true;

ELSIF I_Reference THEN;
    Q_Up := true;
    Q_Down := false;
    GivenValue := I_PosDown;
    StartValue := Q_Position;
    TimeToMove := I_TimeUp + OFFSET_TIME;
    TimeStart:= TIME_TCK();
    IsReference := true;
    ReferenceDone := false;

ELSIF NOT(I_Value = GivenValue) THEN;
    IF NOT (Q_Moving) THEN;
        StartValue := Q_Position;
        GivenValue := I_Value;
        TimeStart := TIME_TCK();
        IF (GivenValue > Q_Position) THEN;
            Q_Up := false;
            Q_Down := true;
            TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((GivenValue - Q_Position) * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown)) ) / 100));
        ELSE;
            Q_Up := true;
            Q_Down := false;
            TimeToMove := DINT_TO_TIME(REAL_TO_DINT( ((Q_Position - GivenValue) * DINT_TO_REAL(TIME_TO_DINT(I_TimeUp))) / 100 ));
        END_IF;
    END_IF;
    

ELSIF (IsReference AND ReferenceDone) THEN;
    IsReference := false;
    Q_Up := false;        
    Q_Down := true;
    GivenValue := StartValue;
    StartValue := Q_Position;
    TimeStart := TIME_TCK();
    TimeToMove := DINT_TO_TIME(REAL_TO_DINT( GivenValue * DINT_TO_REAL(TIME_TO_DINT(I_TimeDown)) ) / 100);

ELSIF NOT(Q_Moving) THEN;
    //Nothing todo;
    RETURN;

END_IF;

// ----- End Of Inputanalysis --------------------------------------------------//

M1: ;

//Calculate Position on Moving
IF(Q_Moving) THEN;
    T_Moved := (TIME_TCK() - TimeStart);

    IF(TimeToMove = ZERO_T) THEN;
        TimeToMove := T_Moved;
    END_IF;

    IF (Q_Up) THEN;
        T_CalcBaseTime := I_TimeUp;
    ELSE;
        T_CalcBaseTime := I_TimeDown;
    END_IF;
        
    T_CurValue := 100 * (DINT_TO_REAL(TIME_TO_DINT(T_Moved)) / DINT_TO_REAL(TIME_TO_DINT(T_CalcBaseTime)));

    IF Q_Up THEN
        T_CurValue := (StartValue - T_CurValue);
    ELSE;
        T_CurValue := (StartValue + T_CurValue);
    END_IF;

    IF(T_Moved > TimeToMove) THEN;
        T_Stop := true;
    END_IF;
END_IF;


IF(T_Stop) THEN;
    IF(Q_Up) THEN;
        LastDirection := UP;
    ELSE;
        LastDirection := DOWN;
    END_IF;

    Q_Up := false;
    Q_Down := false;
    T_Moved := ZERO_T;
    TimeToMove := ZERO_T;
    TimeStart := ZERO_T;
    StartLock := TIME_TCK();
    GivenValue := I_Value;

    IF(IsReference) THEN;
        ReferenceDone := true;
    END_IF;
END_IF;

IF(T_CurValue <= 0) THEN;
    Q_Position := 0.0;
ELSIF(T_CurValue > 100) THEN;
    Q_Position := 100.0;
ELSE;
    Q_Position := T_CurValue;
END_IF;

Q_Moving := (Q_Up OR Q_Down);
Q_TimeToDest := (TimeToMove - T_Moved);


END: ; //Function End

END_FUNCTION_BLOCK

Wobei ich immer noch die oben genannten unschönheiten im Code habe und für konstruktive Kritik dankbar bin!

Gruß chomp
 
Etwas eleganter ist es, wenn du die Abfrage mit den vielen "ELSEIF" gegen eine "CASE" Anweisung ersetzt.
Und...
"GOTO" geht gar nicht, kann man wesentlich eleganter mit "IF" lösen...
 
Hallo StefanK,

danke fürs Feedback. Ja das Thema mit den GOTOs, ich bin auch kein Freund davon und prinzipiell auf dem gleichen Standpunkt wie du. Allerdings gilt auch, keine Ausnahme ohne Regel. Im konkreten Fall könnte man anstelle des GOTO den unteren, ebenfalls von dir kritisierten Block, in eine ELSE Zweig packen und das GOTO wäre raus, ob es das aber so viel übersichtlicher macht stelle ich an der Stelle in Frage. In der Sacher gebe ich dir aber recht!
Zum zweiten (ersten Teil) das CASE. Ich prüfe hier die Eingänge, sprich verschiedene Variablen, bei einem Case Bräuchte ich doch aber nur eine Variable. Oder würdest du hier alle I_xxx auf einen T_xxx mappen und dann ein
Switch (T_xxx) ?

Edit: Zum switch-case nochmal. In C wäre die If-Else Lösung effizienter da hier zu > 80% der I_Close und der I_Open gesetzt würden und diese ganz oben stehen.

Schöne Grüße
chomp
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
In C wäre die If-Else Lösung effizienter da
...
Was mir auch nicht gefällt sind die Codedoppelungen. In c würde ich hier eine Funktion schreiben, aber in SCL habe ich leider keine Idee

Zum GOTO gibt's hier im Forum nen ellenlangen Thread... (ich find die GOTOs oder RETURN in nem SCL Code auch nicht so toll, aber das ist Ansichtssache)

Effizienz ist in SPS-Programmen in aller Regel nebensächlich... Viel wichtiger ist einfach (auch von anderen Kollegen, Inbetriebnehmern, Instandhaltern, von Dir nach 5 Jahren...) zu verstehender Code... Und SCL ist nicht C... In Deinem Code fehlen mir sämtliche Kommentare!

Ansonsten kannst Du auch in einer SPS Funktionen (FC) und Funktionsbausteine (FB) für wiederkehrende Aufgaben erstellen, und diese dann in Deinem Code aufrufen.
 
Hallo StefanK,

Zum zweiten (ersten Teil) das CASE. Ich prüfe hier die Eingänge, sprich verschiedene Variablen, bei einem Case Bräuchte ich doch aber nur eine Variable. Oder würdest du hier alle I_xxx auf einen T_xxx mappen und dann ein
Switch (T_xxx) ?

chomp

Ich habe jetzt gerade kein Step7 zur Hand, aber in anderen Sprachen sind solche Konstrukte möglich:

Code:
CASE TRUE OF
[COLOR=#333333]I_Open :
[/COLOR]...
I_Close :
...
...
ELSE
...
END_CASE
 
Und SCL ist nicht C...
Natürlich nicht, so war das auch nicht gemeint. Nur war das eben meine Überlegung dazu. Das das mit der Effizenz nicht so eine Rolle spielen soll? Hm, ok in meiner kleinen Haussteuerung wohl schon, da wird sich auch meine kleine CPU langweilen, aber trifft das auch auf Industrieanlagen zu?

Code:
CASE TRUE OF 
   [COLOR=#333333]I_Open : [/COLOR]... 
   I_Close : ... 
   ... ELSE 
   END_CASE

Ok, das habe ich probiert:
"Der CASE-Ausdruck muss vom Typ INT sein." Hätte ich jetzt auch so erwartet.

Danke für die Hinweise.

Gruß chomp
 
Zuviel Werbung?
-> Hier kostenlos registrieren
wenn du bei uns in der Firma aufschlagen solltest, dann vergiss alles was in SCL Programmiert wird!
In FUP! SCL und AWL ist zwar möglich, muss aber im Einzelfall von uns freigegeben werden (also vor allem entsprechend mit vernünftigen Kommentaren versehen sein und vernünftig gekapselt sein!)
ca., 98% lässt sich in FUP programmieren ist dann auch von 95% der Instand Halter lesbar! wenn der Rest noch entsprechend Kommentiert ist gibt es keine Probleme bei IBN und weiterhin.

Alles in SCL und du bist von vorne heraus auf der Abschussliste!

Warum nicht gleich in FUP?

Warte mal auf die entsprechenden Kommentare der reinen Prog-Fraktion ;)

SCL ist nun mal bei den Instand haltern ein rotes Tuch!

Abgekapselte Bausteine für Datenübertragung, Auswertung, . . . OK wenn entsprechend kommentiert -> OK
Aber die reine Grundfunktion des Programms sollte für alle verständlich sein -> FUP (Ev KOP)

Wer anders kommt, kann alles bei "0" beginnen!
 
Zuletzt bearbeitet:
ca., 98% lässt sich in FUP programmieren ist dann auch von 95% der Instand Halter lesbar!
Halte ich beides für'n Gerücht.
:p



SCL ist nun mal bei den Instand haltern ein rotes Tuch!
Halte mich für einen. Doch da ich mehr im Automotiv zu Hause bin, geht's mir eher mit FUP so.
Also ruhig mal über'n Tellerrand schauen. Nicht jede Firma ist gleichbedeutend mit dem Rest der Welt.
;)



Mal davon abgesehen - chomp programmiert da Rollläden. Ich denke mal, wir haben's hier mit 'nem Häuslebauer zu tun. Und wenn dem so ist, muss das Ganze hauptsächlich einer verstehen -> er selbst.
:ROFLMAO:



Aber in einem muss ich Dir Recht geben:
vor allem entsprechend mit vernünftigen Kommentaren versehen sein
*ACK*
 
Warte mal auf die entsprechenden Kommentare der reinen Prog-Fraktion
Hier meine Kommentar:

Für reine Logik, finde ich KOP und FUP sind klar das logische Wahl.
Logik geht auch in SCL, eigentlich besser als in AWL.
Der Nachteil bei SCL ist das es in Siemens STEP7 v5x kein gute online-Ansicht dafür gibt. In KOP, FUP und AWL hat mein ein Online Beobachtung der eine enorme hilfe bie der Fehlersuche ist. Es gibt auch eine online Ansicht für SCL, aber es ist sehr primitiv und ich verwende es nur in absoluten Notfall.
In STEP7 v11, v12 (TIA) sollte der online Ansicht für SCL viel verbessert sein. Ich habe es nicht probiert, aber habe grosse Erwartungen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jo die SCL-Diagnose ist schwieriger als AWL oder FUP, dafür gibts in SCL Programmfluss-Kontstrukte aus Hochsprachen und die AWL, die der Compiler rausspuckt sei wohl auch recht gut (zumindest hab ich das stelleweise im Forum so aufgeschnappt).
 
Zurück
Oben