Fehlermeldung bei SCL-Programm

Zuviel Werbung?
-> Hier kostenlos registrieren
Das ist halt der Return Wert der Funktion. In deinem Fall ein Integer Wert.

Aber der Fehler kommt doch, wenn du die SCL Quelle übersetzen willst?

Der Compiler sagt dir, dass er keinen Baustein kompilieren kann weil er den FC (Zielbaustein) nicht öffnen kann.

Der Aufruf ist nochmal ne andere Geschichte.

Lösche mal den Fc1 in deinem Projektordner (symbol NICHT löschen).

Der Fehler kommt nach der Übersetzung der SCL Quelle im SCL Editor. Meinst du damit, dass ich den Inhalt des FCs löschen soll?

Da stellt sich noch ne allgemeine Frage für mich.

...
END_FOR;
SelectionSort := 100; (1)
END_FUNCTION

(1) bedeutet diese Zeile nicht, dass quasi der Rückgabewert dieser Funktion (Ret_Val) immer eine 100 zurück gibt?

Hi,

Code:
// SCL-Programmbeispiel-SelectionSort
FUNCTION SelectionSort : INT
 
VAR_IN_OUT // Variablendeklaration
arrValues : ARRAY[20,43,10,6,18] OF INT;
END_VAR
VAR_TEMP
Idx1, Idx2, MaxIdx, MaxVal, MAXSIZE : INT;
END_VAR
 
[COLOR=red]MAXSIZE := LEN(arrValues); // Bestimmung der Länge des Feldes[/COLOR]
 
FOR Idx1 := MAXSIZE TO 1 BY -1 DO // Werte des Feldes erfassen
MaxVal := arrValues[Idx1];
MaxIdx := Idx1;

hier liegt meiner Meinung nach der Fehler, ist LEN ein selbst geschriebener Baustein um die Feldlänge zu ermitteln?

Oder willst Du den in SCL integrierten LEN benutzen? Der ist allerdings nur für Strings und das kann so nicht funktionieren.

Gruss Daniel

Ja genau.. Ich wollte die Funktion LEN für SCL zur Bestimmung der Feldlänge benutzen. Stimmt, sie funtioniert nur für STRINGs. Gibt es denn auch so eine Funktion für ein ARRAY-Feld oder muss man was eigenes zusammenbauen?

Die Array-Deklaration
Code:
arrValues : ARRAY[20,43,10,6,18] OF INT;
erscheint etwas sonderbar, bist du sicher dass du ein 5-dimensionales Array willst?
C-Syntax kannste nicht 1:1 übernehmen, besonders bei den Array funktioniert das so nicht.

Ebenfalls das LEN glaube ich nicht, dass er dir die Arraygrösse ausliest.

Array deklaration mit Initialwerten:
Code:
arrValues: array[1..5] of INT := 20, 43, 10, 6, 18;

weitere Details --> siehe in der Hilfe vom SCL-Editor nach

Hast mich erwischt^^... das hatte ich so aus der C-Programmierung übernommen. Für mich, und damit mein Programm funktioniert, müsste ich diese Variable so deklarieren:

arrValues: ARRAY[0..4] of INT := 20, 43, 10, 6, 18;

Aber wenn man nun keine Anfangswerte in einem FC zuweisen kann, wie macht man das denn dann? Sollte ich statt dessen lieber ein FB verwenden und dort dann die nötigen Parameter deklarieren? Die SelectionSort-Funktion würde ich dann im FB aufrufen über ein FC. Macht man das so?
 
... um dir nun sinnvoll weiterhelfen zu können ... wie sieht nun nach den angeregten Korrekturen dein Baustein wirklich aus ? Was bezweckst du damit ? Deine Function arbeitet mit Übergabewerten. Warum willst du die vorbesetzen ? Das würde auch bei einem FB nicht mit der Schnittstelle IN_OUT funktionieren.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So sieht nun mein Programm aus:

// SCL-Programmbeispiel-SelectionSort
FUNCTION SelectionSort : INT;

VAR_IN_OUT // Variablendeklaration
arrValues : ARRAY[0..4] OF INT := 20,43,10,6,18;
END_VAR
VAR_TEMP
Idx1, Idx2, MaxIdx, MaxVal : INT;
MAXSIZE : INT := 4;
END_VAR
BEGIN
FOR Idx1 := MAXSIZE TO 1 BY -1 DO // Werte des Feldes erfassen
MaxVal := arrValues[Idx1];
MaxIdx := Idx1;

FOR Idx2 := 0 TO Idx1-1 DO // Bestimmung des größten Wertes der Zelle aus dem Feld
IF arrValues[Idx2] > MaxVal THEN // und deren Indexübernahme
MaxVal := arrValues[Idx2];
MaxIdx := Idx2;
END_IF;
END_FOR;

IF MaxIdx < Idx1 THEN // größter Wert der hochwertigsten Zelle übergeben
arrValues[MaxIdx] := arrValues[Idx1];
arrValues[Idx1] := MaxVal;
END_IF;
END_FOR;
SelectionSort := 100;
END_FUNCTION
------------------
Zusätzlich zur Veränderung des Programms habe ich den RET_VAL-Parameter zum MW100 im OB1 zugewiesen:

CALL "SelectionSort"
RET_VAL:=MW100

Im KOP/AWL/FUP-Editor wird als Fehler für den OB1 unten im Feld nur noch das hier angezeigt:
SCL-Uebung-TO\SIMATIC 400(1)\CPU 412-3 H\...\OB1 - <offline>

hoffe das nützt euch was als info
 
Deine Function arbeitet mit Übergabewerten. Warum willst du die vorbesetzen ? Das würde auch bei einem FB nicht mit der Schnittstelle IN_OUT funktionieren.

Mit Übergabewerten meinte ich das ARRAY.
Schade, dass du dazu keine Stellung genommen hast.

In jedem Fall ... das mußt du im OB1-Aufruf natürlich auch beschalten - also irgendwo dieses Element anlegen (z.B. in einem DB) und dann dem FC übergeben.

Wie auch in C muß bei Step7 jeder Schnittstellen-Parameter beschaltet werden (zumindestens bei einer Function und bei Variablen, die byRef übergeben werden).

Gruß
Larry

Ach ja - nochmal : was bezweckst du ...?
 
Zuletzt bearbeitet:
... um dir nun sinnvoll weiterhelfen zu können ... wie sieht nun nach den angeregten Korrekturen dein Baustein wirklich aus ? Was bezweckst du damit ? Deine Function arbeitet mit Übergabewerten. Warum willst du die vorbesetzen ? Das würde auch bei einem FB nicht mit der Schnittstelle IN_OUT funktionieren.

Gruß
Larry

Mein Ziel ist es dieses Programm zu testen/beobachten. Was muss ich also vorher alles eingestellt haben damit es funktioniert? Bisher habe ich nur die SCl-Quelle und einen OB1,wodrin der Aufruf mit CALL "SelectionSort" steht und der RET_VAL:=MW100 steht. Ein FC ohne Inhalt habe ich auch noch.

gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit Übergabewerten meinte ich das ARRAY.
Schade, dass du dazu keine Stellung genommen hast.

In jedem Fall ... das mußt du im OB1-Aufruf natürlich auch beschalten - also irgendwo dieses Element anlegen (z.B. in einem DB) und dann dem FC übergeben.

Wie auch in C muß bei Step7 jeder Schnittstellen-Parameter beschaltet werden (zumindestens bei einer Function und bei Variablen, die byRef übergeben werden).

Gruß
Larry

Ach ja - nochmal : was bezweckst du ...?



Ich wusste es ja nicht bsser, deswegen die Übergabewerte. Eigentlich dachte ich dass das beobachten/testen auch nur mit dem Scl Editor klappt ohne, dass ich dazu die Bausteine realisieren muss.

gruß
 
Naja ... das klappt in C doch auch nicht wirklich ...
Du mußt schon die Schnittstellen beschalten ...

Wo stehst du jetzt ...?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,

Achtung Wild! Erste Variante über Any Pointer.

Code:
/////////////////////////////////////////////////
// Datenbaustein mit den Daten
DATA_BLOCK Daten
  STRUCT
    arrValues : ARRAY[0..4] OF INT := 20,43,10,6,18;
    RetVal : INT;     
  END_STRUCT
BEGIN

END_DATA_BLOCK

/////////////////////////////////////////////////
// SCL-Programmbeispiel-SelectionSort
FUNCTION SelectionSort : INT

VAR_INPUT // Variablendeklaration
  //arrValues : ARRAY[0..4] OF INT := 20,43,10,6,18;
  arrValues : ANY;
END_VAR

VAR_TEMP
  tAny : ANY;
  ptArrValues AT tAny : STRUCT
    id: BYTE;
    DataType: BYTE;
    Lenght: WORD;
    DBNr: WORD;
    Byte_Pointer: DWORD;
  END_STRUCT;    
  tAdr : INT;
  tLen : INT;
  Idx1, Idx2, MaxIdx, MaxVal : INT;
  MAXSIZE : INT;
END_VAR

BEGIN

  tAny := arrValues;
  
  tAdr := DWORD_TO_INT(SHR(IN:=SHL(IN:=ptArrValues.Byte_Pointer,N:=8),N:=11));
  tLen := WORD_TO_INT(ptArrValues.Lenght);
  MAXSIZE := tLen - 1;
  
  FOR Idx1 := MAXSIZE TO 1 BY -1 DO // Werte des Feldes erfassen

    MaxVal := WORD_TO_INT(WORD_TO_BLOCK_DB(ptArrValues.DBNr).DW[tAdr+(Idx1*2)]); //arrValues[Idx1];
    MaxIdx := Idx1;

    FOR Idx2 := 0 TO Idx1-1 DO // Bestimmung des größten Wertes der Zelle aus dem Feld
      IF WORD_TO_INT(WORD_TO_BLOCK_DB(ptArrValues.DBNr).DW[tAdr+(Idx2*2)]) > MaxVal THEN //arrValues[Idx2] > MaxVal THEN // und deren Indexübernahme
        MaxVal := WORD_TO_INT(WORD_TO_BLOCK_DB(ptArrValues.DBNr).DW[tAdr+(Idx2*2)]); //arrValues[Idx2];
        MaxIdx := Idx2;
      END_IF;
    END_FOR;

    IF MaxIdx < Idx1 THEN // größter Wert der hochwertigsten Zelle übergeben
      WORD_TO_BLOCK_DB(ptArrValues.DBNr).DW[tAdr+(MaxIdx*2)] := WORD_TO_BLOCK_DB(ptArrValues.DBNr).DW[tAdr+(Idx1*2)]; //arrValues[MaxIdx] := arrValues[Idx1];
      WORD_TO_BLOCK_DB(ptArrValues.DBNr).DW[tAdr+(Idx1*2)] := INT_TO_WORD(MaxVal); //arrValues[Idx1] := MaxVal;
    END_IF;

  END_FOR;

  SelectionSort := 100;

END_FUNCTION

/////////////////////////////////////////////////
// Bausteinaufruf im OB1
ORGANIZATION_BLOCK OB1

VAR_TEMP
  // reserviert
  info : ARRAY[0..19] OF BYTE;
  // temporäre Variablen

END_VAR

BEGIN

  Daten.RetVal := SelectionSort(Daten.arrValues);

END_ORGANIZATION_BLOCK
Gruss Daniel
 
Zuletzt bearbeitet:
Hi,

etwas übersichtlicher über einen UDT.

Code:
/////////////////////////////////////////////////
// Anwender Datentyp
TYPE UDT_Values
  STRUCT
    arrValues : ARRAY[0..4] OF INT := 20,43,10,6,18;
  END_STRUCT
END_TYPE

/////////////////////////////////////////////////
// Datenbaustein mit den Daten
DATA_BLOCK Daten
  STRUCT
    arrValues : UDT_Values;
    RetVal : INT;     
  END_STRUCT
BEGIN

END_DATA_BLOCK

/////////////////////////////////////////////////
// SCL-Programmbeispiel-SelectionSort
FUNCTION SelectionSort : INT

VAR_IN_OUT // Variablendeklaration
  //arrValues : ARRAY[0..4] OF INT := 20,43,10,6,18;
  arrValues : UDT_Values;
END_VAR

VAR_TEMP
  Idx1, Idx2, MaxIdx, MaxVal : INT;
  MAXSIZE : INT;
END_VAR

BEGIN

  MAXSIZE := 4;
  
  FOR Idx1 := MAXSIZE TO 1 BY -1 DO // Werte des Feldes erfassen

    MaxVal := arrValues.arrValues[Idx1];
    MaxIdx := Idx1;

    FOR Idx2 := 0 TO Idx1-1 DO // Bestimmung des größten Wertes der Zelle aus dem Feld
      IF arrValues.arrValues[Idx2] > MaxVal THEN //arrValues[Idx2] > MaxVal THEN // und deren Indexübernahme
        MaxVal := arrValues.arrValues[Idx2]; //arrValues[Idx2];
        MaxIdx := Idx2;
      END_IF;
    END_FOR;

    IF MaxIdx < Idx1 THEN // größter Wert der hochwertigsten Zelle übergeben
      arrValues.arrValues[MaxIdx] := arrValues.arrValues[Idx1]; //arrValues[MaxIdx] := arrValues[Idx1];
      arrValues.arrValues[Idx1] := MaxVal; //arrValues[Idx1] := MaxVal;
    END_IF;

  END_FOR;

  SelectionSort := 100;

END_FUNCTION

/////////////////////////////////////////////////
// Bausteinaufruf im OB1
ORGANIZATION_BLOCK OB1

VAR_TEMP
  // reserviert
  info : ARRAY[0..19] OF BYTE;
  // temporäre Variablen

END_VAR

BEGIN

  Daten.RetVal := SelectionSort(arrValues:=Daten.arrValues);

END_ORGANIZATION_BLOCK

Nachtrag: Die MAXSIZE könnte man wieder über den ANY ermitteln.

Gruss Daniel
 
Zuletzt bearbeitet:
Nachtrag: Die MAXSIZE könnte man wieder über den ANY ermitteln.

Gruss Daniel


hi,
ich muss zugeben, dass ich es mir viel zu einfach vorgestellt hatte. Ich habe mal deine zweite Variante versucht zu testen, wobei nach der Übersetzung erneut Fehlermeldungen auftraten. Funktioniert das denn bei dir?
Fehlermeldungen:

Baustein: UDT_Values
F: Z 00003 S 00001: Symbolischer Bausteinname: 'UDT_Values' nicht erkannt.
Baustein: Daten
F: Z 00011 S 00001: Symbolischer Bausteinname: 'Daten' nicht erkannt.
Baustein: SelectionSort
F: Z 00022 S 00001: Symbolischer Baustinname: 'SelectionSort' nicht erkannt.
Baustein: OB1
F: Z 00074 S 00009: Der Bezeichner existiert nicht.
F: Z 00074 S 00009: Fehlerhafte Variable, der Punkt ist nicht zulässig.
F: Z 00074 S 00032: Der Baustein SelectionSort konnte nicht gefunden oder kopiert werden.
F: Z 00074 S 00032: Funktion nicht definiert.
F: Z 00074 S 00050: Der Bezeichner existiert nicht.
F: Z 00074 S 00050: Fehlerhafte Vairable, der Punkt ist nicht zulässig.
W: Der Code-Generator wurde wegen eines Fehlers nicht aufgerufen.
Ergebnis 9 Fehler, 1 Warnung(en)
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Kann es sein, dass ich die Variablendeklarationen aus dem SCL-Programm zusätzlich noch in die Bausteine eintragen muss?

z.B. die Strukturelemente bei UDT aus dem Programm in einem Baustein UDT1 wieder auflisten.
 
Zuletzt bearbeitet:
Code:
Baustein: UDT_Values
F: Z 00003 S 00001: Symbolischer Bausteinname: 'UDT_Values' nicht erkannt.
Baustein: Daten
F: Z 00011 S 00001: Symbolischer Bausteinname: 'Daten' nicht erkannt.
Baustein: SelectionSort
F: Z 00022 S 00001: Symbolischer Baustinname: 'SelectionSort' nicht erkannt.

Diese Bausteine müssen in der Symbolik stehen.
SCL kann nicht einfach den UDT_Values erstellen ohne die UDT Nummer zu wissen. In der Symbolik muss dann in etwa stehen

UDT1 | UDT_Values

Wenn diese 3 Bausteine in der Symbolik stehen sollten diese Fehler schon mal weg sein.



Code:
Baustein: OB1
F: Z 00074 S 00009: Der Bezeichner existiert nicht.
F: Z 00074 S 00009: Fehlerhafte Variable, der Punkt ist nicht zulässig.
F: Z 00074 S 00032: Der Baustein SelectionSort konnte nicht gefunden oder kopiert werden.
F: Z 00074 S 00032: Funktion nicht definiert.
F: Z 00074 S 00050: Der Bezeichner existiert nicht.
F: Z 00074 S 00050: Fehlerhafte Vairable, der Punkt ist nicht zulässig.
W: Der Code-Generator wurde wegen eines Fehlers nicht aufgerufen.
Ergebnis 9 Fehler, 1 Warnung(en)
Wenn oberer Teil Fehlerfrei ist, sollte hier nicht viel übrig bleiben.

Wenn Fehlerfrei übersetzt wurde, müssen im Ordner Bausteine die UDT, der DB und die FC stehen.

Schau erstmal dass komplett Fehlerfrei übersetzt wird und du die Abläufe verstehst erst dann schlag dich mit dem Any rum.
 
Also wenn in der Symbolik folgendes als Beispiel steht funktioniert das Kompilieren

UDT_Values UDT 1 UDT 1
Daten DB 1 DB 1
SelectionSort FC 1 FC 1


bike
 
Hi,

die einfachste Variante.

Code:
// SCL-Programmbeispiel-SelectionSort
FUNCTION SelectionSort : INT

CONST
  MAXSIZE := 4;
END_CONST

VAR_IN_OUT // Variablendeklaration
  arrValues : ARRAY[0..MAXSIZE] OF INT;
END_VAR

VAR_TEMP
  Idx1, Idx2, MaxIdx, MaxVal : INT;
END_VAR

BEGIN

  FOR Idx1 := MAXSIZE TO 1 BY -1 DO // Werte des Feldes erfassen
    MaxVal := arrValues[Idx1];
    MaxIdx := Idx1;
    
    FOR Idx2 := 0 TO Idx1-1 DO // Bestimmung des größten Wertes der Zelle aus dem Feld
      IF arrValues[Idx2] > MaxVal THEN // und deren Indexübernahme
        MaxVal := arrValues[Idx2];
        MaxIdx := Idx2;
      END_IF;
    END_FOR;
    
    IF MaxIdx < Idx1 THEN // größter Wert der hochwertigsten Zelle übergeben
      arrValues[MaxIdx] := arrValues[Idx1];
      arrValues[Idx1] := MaxVal;
    END_IF;
  END_FOR;
  SelectionSort := 100;

END_FUNCTION
Gruss Daniel
 
Hi,

die einfachste Variante.

Code:
// SCL-Programmbeispiel-SelectionSort
FUNCTION SelectionSort : INT

CONST
  MAXSIZE := 4;
END_CONST

VAR_IN_OUT // Variablendeklaration
  arrValues : ARRAY[0..MAXSIZE] OF INT;
END_VAR

VAR_TEMP
  Idx1, Idx2, MaxIdx, MaxVal : INT;
END_VAR

BEGIN

  FOR Idx1 := MAXSIZE TO 1 BY -1 DO // Werte des Feldes erfassen
    MaxVal := arrValues[Idx1];
    MaxIdx := Idx1;
    
    FOR Idx2 := 0 TO Idx1-1 DO // Bestimmung des größten Wertes der Zelle aus dem Feld
      IF arrValues[Idx2] > MaxVal THEN // und deren Indexübernahme
        MaxVal := arrValues[Idx2];
        MaxIdx := Idx2;
      END_IF;
    END_FOR;
    
    IF MaxIdx < Idx1 THEN // größter Wert der hochwertigsten Zelle übergeben
      arrValues[MaxIdx] := arrValues[Idx1];
      arrValues[Idx1] := MaxVal;
    END_IF;
  END_FOR;
  SelectionSort := 100;

END_FUNCTION
Gruss Daniel



Aha ok,
dafür müsste ich jetzt nur noch in der Symboltabelle z.B. einen FC1 als "SelectionSort" benennen. Bei dieser Variante haben die Zellen aber keinen Inhalt. Was würde denn beim Beobachten der Variablen angezeigt werden? - Irgendwelche Zahlen?!

Fehlt bei diesem Quellcode nicht auch noch der Aufruf im OB1 so wie du das bei deinen anderen Varianten getan hast?

und die letzte Frage vorerst:

Was bedeutet die Fehlermeldung "Der Baustein-Ordner(ONLINE) konnte nicht erreicht werden" ?

Diese Fehlermeldung entsteht beim Brillensymbol im SCL Editor, wenn ich also die Variablen beobachten möchte.
progress.gif
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,

Aha ok,
dafür müsste ich jetzt nur noch in der Symboltabelle z.B. einen FC1 als "SelectionSort" benennen. Bei dieser Variante haben die Zellen aber keinen Inhalt. Was würde denn beim Beobachten der Variablen angezeigt werden? - Irgendwelche Zahlen?!

nein, Du musst natürlich den DB und den Aufruf noch mit reinpacken.
Achtung! Das Array im DB muss exakt dem in Baustein entsprechen.

Fehlt bei diesem Quellcode nicht auch noch der Aufruf im OB1 so wie du das bei deinen anderen Varianten getan hast?

ja, siehe oben.

Was bedeutet die Fehlermeldung "Der Baustein-Ordner(ONLINE) konnte nicht erreicht werden" ?

Sind da mehrere Ordner in Deinem Projekt?
Lege die Quelle mal in dem Ordner unter der CPU ab, was passiert da?

Gruss Daniel
 
Zurück
Oben