IF Abfrage in SCL

fbeine

Level-2
Beiträge
134
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe eine Problem mit eine If-Abfrage:

Code:
FUNCTION FC113 : VOID

VAR_TEMP
    // temporäre Variablen
    I:INT;                              // Schmiervariable in For-Schleifen
    J:INT;                              // Schmiervariable in For-Schleifen
END_VAR 
VAR_INPUT
    // INPUT Variablen deklarieren
    bPositionierung_starten:BOOL;       // Startbefehl um die Posiitonierung zu starten
    iRollendurchmesser:INT;             // Rollendurchmesser des Jumbos im Abwickler
    iDW_Soll:INT;                       // Datenwort, wo die Positionsollwerte in den DBs stehen
    iDB_Zaehlerkarte:BLOCK_DB;          // Datenbaustein Zählerkarte
    iDW_Zaehlerkarte:INT;               // Datenwort Zählerkarte, wo die Position in den DBs stehen
    
END_VAR
VAR_OUTPUT
    // OUTPUT Variablen deklarieren
    bRausfahren:BOOL;                   // Motor muss rausfahren
    bReinfahren:BOOL;                   // Motor muss reinfahren
END_VAR
VAR_IN_OUT
    // IN_OUTPUT Variablen deklarieren
    bPosition_OK:BOOL;                  // Positionierung abgeschlossen, POS_OK
    bPositionierung_REIN:BOOL;          // Motor ist aktuell am Positionieren / REINfahren, POS_ON
    bPositionierung_RAUS:BOOL;          // Motor ist aktuell am Positionieren / RAUSfahren, POS_ON
END_VAR

// Anweisungsteil

    CASE iRollendurchmesser OF
    100..150:          
        IF bPositionierung_starten = true THEN
            
            // Richtstab reinfahren starten
            IF bPositionierung_REIN = false AND DB41.DW[iDW_Soll] > iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] THEN
                bReinfahren := true;
                bPositionierung_REIN := true;
            END_IF;
            // Richtstab reinfahren Position erreicht
            IF bPositionierung_REIN = true AND DB41.DW[iDW_Soll] <= iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] THEN  
                bReinfahren := false;
                bPositionierung_REIN := false;
                bPosition_OK := true;
            END_IF;
            
            // Richtstab rausfahren starten
            IF DB41.DW[iDW_Soll] < iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] AND bPositionierung_RAUS = false THEN
                bRausfahren := true;
                bPositionierung_RAUS := true;
            END_IF;
            // Richtstab rausfahren Position erreicht
            IF bPositionierung_RAUS = true AND DB41.DW[iDW_Soll] >= iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] THEN
                bRausfahren := false;
                bPositionierung_RAUS := false;
                bPosition_OK := true;
            END_IF;
   
            
            
        END_IF;

        
    80..99:
        ;
        
    60..79:
        
        ;
    40..59:
        
        ;
    1..39:
        
        ;

  ELSE:
    // Anweisungen_ELSE
    ;
  END_CASE;
  
END_FUNCTION

Bei diesen Code bekomme ich in allen IF-Anweisungen der inneren IF-Schleifen im CASE folgende Fehlermeldungen:
==> Unzulässige Operandentypen
==> Ausdruck muss von Datentyp BOOL sein

Die Datenwörter in den DBs sind alle in INT deklariert.

vielen Dank im voraus
Frank
 
Hallo, probier es mal mit Klammern:



// Richtstab reinfahren starten
IF (bPositionierung_REIN = false) AND (DB41.DW[iDW_Soll] > iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte]) THEN
bReinfahren := true;
bPositionierung_REIN := true;
END_IF;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Klappt mit Klammern leider auch nicht.

Habe aber folgendes experementel ermittelt:

IF bPositionierung_REIN = false AND iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] <> DB41.DW[iDW_Soll] THEN
bReinfahren := true;
bPositionierung_REIN := true;
END_IF;

mit "<>" klappt es mit "<" nicht .... :?:
 
Du musst um einen DB per Variable aufzurufen die Funktion WORD_TO_BLOCK_DB nutzen und für die DB brauchst du eine Word Variable.

Des weiteren beginne generell eine IF Variable mit
IF NOT bPositionierung_REIN AND (

und nicht

IF bPositionierung_REIN = true

Ich hoffe ich konnte helfen !!!

Gruss
Thomas
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Thomas,

wo muss ich denn die BLOCK_DB deklarieren ?
wie müsste denn der Code aussehen ?

ich habe folgendes getestet, ohne erfolg ...

VAR_INPUT
// INPUT Variablen deklarieren
bPositionierung_starten:BOOL; // Startbefehl um die Posiitonierung zu starten
iRollendurchmesser:INT; // Rollendurchmesser des Jumbos im Abwickler
iDW_Soll:INT; // Datenwort, wo die Positionsollwerte in den DBs stehen
iDB_Zaehlerkarte:BLOCK_DB; // Datenbaustein Zählerkarte INT
wDB_Zaehlerkarte:WORD; // Datenbaustein Zählerkarte WORD
iDW_Zaehlerkarte:INT; // Datenwort Zählerkarte, wo die Position in den DBs stehen
END_VAR

VAR_IN_OUT
// IN_OUTPUT Variablen deklarieren
bPosition_OK:BOOL; // Positionierung abgeschlossen, POS_OK
bPositionierung_REIN:BOOL; // Motor ist aktuell am Positionieren / REINfahren, POS_ON
bPositionierung_RAUS:BOOL; // Motor ist aktuell am Positionieren / RAUSfahren, POS_ON
BLOCK_DB_Zaehlerkarte:BLOCK_DB;
END_VAR



// Anweisungsteil
BLOCK_DB_Zaehlerkarte := WORD_TO_BLOCK_DB(wDB_Zaehlerkarte);
CASE iRollendurchmesser OF
100..150:
IF bPositionierung_starten = true THEN

// Richtstab reinfahren starten
// IF bPositionierung_REIN = false AND iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] < DB41.DW[iDW_Soll] THEN
IF bPositionierung_REIN = false AND BLOCK_DB_Zaehlerkarte.DW[iDW_Zaehlerkarte] < DB41.DW[iDW_Soll] THEN
bReinfahren := true;
bPositionierung_REIN := true;


gruss Frank
 
Block_DB geht nur so zu verwenden:

Beispiel für Datentypen für Parameter
Code:
FUNCTION ABSTAND : REAL
VAR_INPUT
    MeinDB : BLOCK_DB;
    ZEIT : TIMER ;
END_VAR
VAR_TEMP
    INDEX : INT ;
END_VAR
BEGIN

ABSTAND := DWORD_TO_REAL(MeinDB.DD4) ;

END_FUNCTION
Du mußt die DB-Nummer übergeben und WORD_TO_BLOCK_DB benutzen:

Code:
VAR_INPUT
  // Eingangsparameter
  DB_Nr: INT;
  StartP: INT;
  Anzahl: INT;
 
END_VAR

VAR_IN_OUT
  // Durchgangsparameter
END_VAR

VAR_OUTPUT
 // Ausgangsparameter
  MAXIMUM: DINT;
END_VAR

VAR_TEMP
  // temporäre Variablen
  Wert: DINT;
  I: INT;
END_VAR

BEGIN
  // Anweisungsteil
  MAXIMUM := 0;
 
   FOR I := 1 TO Anzahl DO
       Wert := DWORD_TO_DINT(WORD_TO_BLOCK_DB(INT_TO_WORD(DB_Nr)).DD[StartP+((I-1)*4)]); 
      
       IF MAXIMUM < Wert THEN MAXIMUM := Wert; END_IF;          
END_FOR;
 
Mit Franks Bsp. könnte es dann so aussehen:

Code:
            // Richtstab reinfahren starten 
            IF NOT bPositionierung_REIN AND WORD_TO_INT(DB41.DW[iDW_Soll]) > WORD_TO_INT(iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte]) THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;

SCL weiß leider nicht dass es sich um Intergerwerte handelt. Daher ist ohne Konvertierung "WORD_TO_INT" der Befehl "<>" zulässig, andere Vergleichsbefehle hingegen nicht.


Gruß, Onkel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen alle zusammen,

kann sein, dass ich mich zu dumm anstelle, aber ich bekomme es nicht zum laufen.
Ich habe es folgendermassen versucht:

Code:
VAR_INPUT
    // INPUT Variablen deklarieren
    bPositionierung_starten:BOOL;       // Startbefehl um die Posiitonierung zu starten
    iRollendurchmesser:INT;             // Rollendurchmesser des Jumbos im Abwickler
    iDW_Soll:INT;                       // Datenwort, wo die Positionsollwerte in den DBs stehen
    iDB_Zaehlerkarte:INT;               // Datenbaustein Zählerkarte INT
    iDW_Zaehlerkarte:INT;               // Datenwort Zählerkarte, wo die Position in den DBs stehen
END_VAR


// Richtstab reinfahren starten 
            IF NOT bPositionierung_REIN AND DB41.DW[iDW_Soll] > WORD_TO_BLOCK_DB(INT_TO_WORD(iDB_Zaehlerkarte)).DW[iDW_Zaehlerkarte] THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;

aber es kommen 2 Fehlermeldungen:
==> Unzulässige Operandentypen
==> Der Ausdruck muss von Typ BOOL sein

vieleicht habt ihr ja noch eine zündende Idee ....

Gruss Frank
 
Also nochmal: probier es mal mit Klammern.

// Richtstab reinfahren starten
IF NOT bPositionierung_REIN AND ( DB41.DW[iDW_Soll] > WORD_TO_BLOCK_DB(INT_TO_WORD(iDB_Zaehlerkarte)).DW[iDW_Zaehlerkarte] ) THEN
bReinfahren := true;
bPositionierung_REIN := true;
END_IF;

SCL ist PASCAL für S7 !!!
 
So geht es:

Code:
// Richtstab reinfahren starten 
            IF NOT bPositionierung_REIN AND WORD_TO_INT(DB41.DW[iDW_Soll]) > WORD_TO_INT(WORD_TO_BLOCK_DB(INT_TO_WORD(iDB_Zaehlerkarte)).DW[iDW_Zaehlerkarte]) THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;

Such mal in der SCL-Hilfe unter "Vergleichsausdrücke". Man kann Word-Variablen nicht mit > oder < vergleichen, also muß man Variablen, bei denen das Format nicht bekannt ist wohl erst explizit in Int-Variablen umwandeln, damit der Compiler das schluckt.
 
Block_DB geht nur so zu verwenden:

Beispiel für Datentypen für Parameter
Code:
FUNCTION ABSTAND : REAL
VAR_INPUT
    MeinDB : BLOCK_DB;
    ZEIT : TIMER ;
END_VAR
VAR_TEMP
    INDEX : INT ;
END_VAR
BEGIN

ABSTAND := DWORD_TO_REAL(MeinDB.DD4) ;

END_FUNCTION
Du mußt die DB-Nummer übergeben und WORD_TO_BLOCK_DB benutzen:

Code:
VAR_INPUT
  // Eingangsparameter
  DB_Nr: INT;
  StartP: INT;
  Anzahl: INT;
 
END_VAR

VAR_IN_OUT
  // Durchgangsparameter
END_VAR

VAR_OUTPUT
 // Ausgangsparameter
  MAXIMUM: DINT;
END_VAR

VAR_TEMP
  // temporäre Variablen
  Wert: DINT;
  I: INT;
END_VAR

BEGIN
  // Anweisungsteil
  MAXIMUM := 0;
 
   FOR I := 1 TO Anzahl DO
       Wert := DWORD_TO_DINT(WORD_TO_BLOCK_DB(INT_TO_WORD(DB_Nr)).DD[StartP+((I-1)*4)]); 
      
       IF MAXIMUM < Wert THEN MAXIMUM := Wert; END_IF;          
END_FOR;

Wofür stehen die ganzen &# ? #Variable? & ist aber kein "And" , oder?
 
@Django2012

Der Code ist aus 2006, inzwischen hat die Forensoftware einige Versionsänderungen inkl. komplettem Systemwechsel erfahren. Da ist wohl was beim Umformatieren der Texte schiefgelaufen.

: ist ein Doppelpunkt ( : )
( ist Klammer auf ( ( )
) ist Klammer zu ( ) )

usw.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ah. OK. Habe nämlich gestern in nem Siemens Beispiel schon %M10.0 entdeckt. Da war mir % schon nicht klar, das weiß ich mittlerweile. Aber die &# waren jetzt ein bisschen viel des guten ;-= :confused:;)
 
Zurück
Oben