# blkmov in SCL



## Felse (25 März 2009)

Hallo zusammen,

Ich habe folgendes Problem: ich habe in meinem Projekt mehrere Optionsmöglichkeiten zur Auswahl was den Aufbau der Maschine betrifft, diese will ich durch einen Tastendruck in einen zweiten DB "abspeichern" können. Ich will dafür die SFC20 blkmov nutzen, aber wie funzt das in SCL? Hab die SFC aufgerufen, weiß aber nicht genau welche Parameter da rein geschrieben werden müssen. Das hab ich bis jetzt.

```
IF speichern = true 
THEN BLKMOV(SRCBLK := test, // IN: ANY
     DSTBLK := test1  // OUT: ANY
                    );  // INT
END_IF;
```
speichern ist mein Taster
test ist mein Quell - DB
test1 ist mein Ziel - DB
Aber was kommt in die letzte Zeile, da bekomm ich beim Übersetzen immer "Ungültiger oder fehlender Funktionstyp", oder geht das so gar nicht?


----------



## Gebs (25 März 2009)

Hallo Felse,

in Deinem Aufruf fehlt der Ret_Val.

Grüße
Gebs


----------



## Felse (25 März 2009)

Hab ich mir gedacht, weil ich das aus awl so kenne, aber warum fehlt der hier, ich hab den SFC20 doch ganz normal aufgerufen (einfügen - Bausteinaufruf).


----------



## Felse (25 März 2009)

```
IF speichern = true
 
THEN BLKMOV(SRCBLK := test, // IN: ANY
       RET_VAL:= test2.Wert,
       DSTBLK := test1  // OUT: ANY
       );  // INT
END_IF;
```
Wert ist eine INT Variable im DB test2
Geht trotzdem nicht, gleiche Meldung in der letzten Zeile


----------



## Gebs (25 März 2009)

Hallo Felse,

versuch mal in Deinem Bausteinordner den SFC 20 zu erzeugen, vllt. gehts dann.

Grüße
Gebs


----------



## Felse (25 März 2009)

> versuch mal in Deinem Bausteinordner den SFC 20 zu erzeugen, vllt. gehts dann.


Der ist ja da


----------



## Gebs (25 März 2009)

War Blödsinn, was ich geschrieben hab'.


----------



## vierlagig (25 März 2009)

ist test und test1 denn auch ein ANY? wie setzt du den zusammen? wie sieht der aus?


----------



## Felse (25 März 2009)

Äh, nö... Das sind "normale" Globale DBs, aber kannst du mir sagen wie ich da vorgehen muss? Hab nämlich keinen Plan


----------



## Larry Laffer (25 März 2009)

Hallo Felse,
da gibt es doch was von Ratiopharm (ich meine natürlich in der FAQ) :
http://www.sps-forum.de/showthread.php?t=12923


----------



## vierlagig (25 März 2009)

Larry Laffer schrieb:


> Hallo Felse,
> da gibt es doch was von Ratiopharm (ich meine natürlich in der FAQ) :
> http://www.sps-forum.de/showthread.php?t=12923


 
da steht aber leider die SCL-variante noch nicht drin ... die findest du hier: http://sps-forum.de/showthread.php?t=21582


----------



## JesperMP (25 März 2009)

Wie in den anderen Thread schon beschrieben:

In SCL kann man einfach so schreiben:
PLC_data1.vals[2] := PLC_data2.vals[1] ;
oder sogar
PLC_data1.vals := PLC_data2.vals ;
oder eben 
PLC_data1 := PLC_data2 ;

Der compiler kümmert sich dann um wie die Daten transferiert wird.
Wenn die Daten nur wenige sind, wird normale Lade+Transfer verwendet.
Wenn die Daten zu viel sind, wird ein SFC20 aufruf eingefügt.

Wenn Du wirklich SFC20 in SCL aufrufen willst, denn sieht das so aus:


```
FUNCTION Call_SFC20 : void
VAR_TEMP
 iRetval : INT ;
END_VAR
 
iRetval := BLKMOV(SRCBLK :=  PLC_data.vals[1]
       ,DSTBLK := PLC_data.vals[2]
       ); 
 
END_FUNCTION
```
 
edit: Habe das Beispiel etwas erweitert

noch ein edit: Wichtig ist, wenn Quelle und Ziel schon bekannt ist für den Compiler, dann shreibt man einfach _datenx := dateny ;_
Wenn die Daten nicht bekannt ist, weill sie als ANY Paremeter übergeben werden oder der ANY Pointer intern 'gebaut' wird, so braucht man BLKMOV in SCL code.


----------



## Ralle (25 März 2009)

Mit dem SFC20-Aufruf geht das so:


```
FUNCTION_BLOCK FB111

VAR_INPUT
   INANY: ANY;
   OUTANY: ANY;   
END_VAR

VAR_TEMP
    // temporäre Variablen
  Retval: INT;
END_VAR
VAR
    // statische Variablen

END_VAR

Retval := BLKMOV(SRCBLK := INANY  // IN: ANY
       ,DSTBLK := OUTANY  // OUT: ANY
       ); // INT
 
    // Anweisungsteil
    ;
END_FUNCTION_BLOCK
```

Du kannst auch mal hier schauen:

http://www.sps-forum.de/showpost.php?p=25492&postcount=5

Der FC112 könnte vielleicht von dir eingesetzt werden, dann mußt du in SCL nicht die Any selber zusammenbauen, sondern rufst den FC112 auf, DB-Nummr, Start-DW und Länge dran, fertig.


----------



## Felse (25 März 2009)

@ ll  Da hat sich Volker wirklich viel Arbeit gemacht, leider weiß jetzt auch nicht wirklich mehr, keine Ahnung was da jetzt zu tun ist.


----------



## Larry Laffer (25 März 2009)

... und die Beiträge von Vierlagig, Jesper und Ralle helfen dir auch nicht weiter ?

Was willst du denn ver-moven ?


----------



## Felse (25 März 2009)

Erstmal danke für die ganze Hilfe, wenn ich das jetzt testen möchte, müssten doch die Variablen (Aktualwerte) von test in test1 geschrieben werden, oder sehe ich das falsch, das einzige, was ich beobachten kann, ist das sich "Wert" auf -32768 ändert.


----------



## Felse (25 März 2009)

@ larry : doch die haben mir geholfen, das hatte ich geschrieben bevor ich die Beiträge aktualisiert hatte


----------



## Ralle (25 März 2009)

Felse schrieb:


> Erstmal danke für die ganze Hilfe, wenn ich das jetzt testen möchte, müssten doch die Variablen (Aktualwerte) von test in test1 geschrieben werden, oder sehe ich das falsch, das einzige, was ich beobachten kann, ist das sich "Wert" auf -32768 ändert.



Versuch es mal mit dem FC112, das erspart dir den Umgang mit den Any-Variablen.


----------



## Felse (25 März 2009)

Ralle schrieb:


> Versuch es mal mit dem FC112, das erspart dir den Umgang mit den Any-Variablen.


 
Ist vielleicht ne dumme Frage, aber wo find ich den? Muss ich den dann einfach nur in meinem SCL Prog aufrufen?


----------



## Larry Laffer (25 März 2009)

einfach dem Link von Ralle's Beitrag (#13) folgen ...


----------



## Felse (25 März 2009)

Ja gut, also einfach einen awl - Baustein nehmen diesen ganzen Text darein kopieren und diesen Baustein dann in meinem SCL Prog aufrufen oder wie?


----------



## Ralle (25 März 2009)

Felse schrieb:


> Ja gut, also einfach einen awl - Baustein nehmen diesen ganzen Text darein kopieren und diesen Baustein dann in meinem SCL Prog aufrufen oder wie?



Du erzeugst im Quellordner eine AWL-Quelle (Cursor auf den Quellen-Ordner, "Einfügen/St-Software/AWL-Quelle"), öffnest die, kopierst den Code da rein, paßt die FC-Nummer bei Bedarf an, übersetzt die Quelle. Dann steht der Baustein in deinem Bausteinordner. Nun kannst du ihn in SCL aufrufen.


----------



## Felse (25 März 2009)

OK, hab ich so gemacht, hab beim Übersetzen 2 Warnungen erhalten, dass ich sicherstellen soll das mein globaler DB richtig gesetzt ist, den Baustein hat er aber trotzdem erzeugt. Aber wenn ich diesen dann Aufrufe / übersetze ( nach Umbenennen), gehts trotzdem nicht und ich erhalte Fehlermeldungen: Ausdruck nicht korrekt.


```
(AnzahlDBB := 2 // IN: INT
  ,QuellDB := 100 // IN: INT
  ,QuellDW :=  1// IN: INT
  ,ZielDB := 101 // IN: INT
  ,ZielDW :=  1// IN: INT
  ); // INT
```
 
Hab jetzt einfach die Nr des DB eingefügt, da ja INT Werte gefragt waren, oder ? Was muss ich da tun?


----------



## Ralle (25 März 2009)

Felse schrieb:


> OK, hab ich so gemacht, hab beim Übersetzen 2 Warnungen erhalten, dass ich sicherstellen soll das mein globaler DB richtig gesetzt ist, den Baustein hat er aber trotzdem erzeugt. Aber wenn ich diesen dann Aufrufe / übersetze ( nach Umbenennen), gehts trotzdem nicht und ich erhalte Fehlermeldungen: Ausdruck nicht korrekt.
> 
> 
> ```
> ...



Die Warnung ist ok, das ist in diesem Falle normal.
Das ist ein *FC*. FC haben einen Rückgabeparameter, in diesem Falle gebe ich den Retval des SFC20 zurück, also eine Int! Also muß dem Aufruf des FC in SCL eine Zuweisung vorangestellt werden. (Siehe Aufruf des SFC20, genau so).

QuellDW := 1 ????
ZeilDW := 1 ???
Ich würde meinen 0 oder 2, DW liegen immer an geraden Grenzen.


----------



## dalbi (25 März 2009)

Hallo Felse,

eine andere möglichkeit ist den ANY mittels AT Konstrukt direkt zu beschreiben. 

Siehe Beispiel auf der Siemens Seite
http://support.automation.siemens.com/WW/view/de/21946854 

Gruss Daniel


----------



## Felse (25 März 2009)

@ralle


> QuellDW := 1 ????
> ZeilDW := 1 ???
> Ich würde meinen 0 oder 2, DW liegen immer an geraden Grenzen.


Gut das stimmt, daraus hab ich jetzt 0 gemacht. Aber die die Fehlermeldungen bleiben. Ich schreib mal wie ich das denke:
	
	



```
Wert:= (AnzahlDBB := [COLOR=red]Anzahl der beiden DBs zwischen denen getauscht wird also 2[/COLOR] // IN: INT
 ,QuellDB := [COLOR=red]Nr des Quell DB also 100[/COLOR] // IN: INT
 ,QuellDW :=  [COLOR=red]Nr des Quell DW im Quell DB also 0[/COLOR]// IN: INT
 ,ZielDB := [COLOR=#ff0000]Nr des Ziel DB also 101[/COLOR]  // IN: INT
 ,ZielDW := [COLOR=#ff0000]Nr des Quell DW im Ziel DB also 0[/COLOR]// IN: INT
 ); // INT
```
In meinem DB 101 stehen noch keine Variable (außer der Platzhaltervar.) drin. Im DB 100 sind verschiedene Variablen mit verschiedenen Datentypen enthalten.
Ist die Überlegung richtig?


----------



## Ralle (25 März 2009)

Dein FC-Aufruf wäre richtig mit den entsprechenden Zahlen.

Du trägst da normale Int an den FC112 an, entweder fest oder natürlich als Variable. Die DB müssen natürlich existieren und soviele Byte haben, wie kopiert werden sollen. Was gensu in den DB steht (was für Variablen) ist egal, du mußt nur die richtige Länge einstellen.

Bsp: 
Du willst 2 Real ab DW 0 übertragen.
Die Länge von 2 Real ist 8 Byte, also 0 bei QuellDW und 8 bei Anzahl DBB.


----------



## Felse (25 März 2009)

Ich bin total blöd, hab jetzt wie im Bsp von dir 2 real Zahlen im DB 100 angelegt (sonst nix) der DB 101 ist leer. Daraus ergibt sich:


```
Wert:= (AnzahlDBB := 2  // IN: INT
 ,QuellDB := 100 // IN: INT
 ,QuellDW := 0 // IN: INT
 ,ZielDB := 101 // IN: INT
 ,ZielDW := 8// IN: INT
 ); // INT
```
 
Was ist daran noch falsch, ich dreh gleich durch das kann doch nicht so schwer sein.:sb7:


----------



## Larry Laffer (25 März 2009)

ein REAL ist 4 Byte groß ...


----------



## Felse (25 März 2009)

richtig, daher auch:

```
ZielDW := 8// IN: INT
```
oder ist das falsch?


----------



## Ralle (25 März 2009)

Felse schrieb:


> Ich bin total blöd, hab jetzt wie im Bsp von dir 2 real Zahlen im DB 100 angelegt (sonst nix) der DB 101 ist leer. Daraus ergibt sich:
> 
> 
> ```
> ...




```
Wert:= (AnzahlDBB := [COLOR="Red"]8[/COLOR]  // IN: INT
 ,QuellDB := 100 // IN: INT
 ,QuellDW := 0 // IN: INT
 ,ZielDB := 101 // IN: INT
 ,ZielDW := [COLOR="Red"]0[/COLOR]// IN: INT
 ); // INT
```

Auch im DB101 müssen 2 Realzahlen angelegt sein.


----------



## Felse (25 März 2009)

Hab ich alles nach deiner Vorlage geändert, aber das Prob bleibt das gleiche, keine Ahnung was das sein soll.
Habe:
1. zwei DBs (DB 100 , DB101) angelegt
2. in beiden DBs zwei REAL Zahlen angelegt
3. das Prog von Ralle in eine awl - Quelle kopiert, übersetzt und den daraus entsandenen Baustein FC 113 in meinem SCL Prog aufgerufen
4. dieses Prog erstellt 


```
FUNCTION_BLOCK FB6
VAR_TEMP
    // temporäre Variablen
  Wert: INT;
END_VAR
Wert:= (AnzahlDBB := 8  // IN: INT
 ,QuellDB := 100 // IN: INT
 ,QuellDW := 0  // IN: INT
 ,ZielDB := 101 // IN: INT
 ,ZielDW := 0  // IN: INT
 ); // INT 
 
END_FUNCTION_BLOCK
```
 
Aber: das scheiß ding funzt nicht...?


----------

