# Brauche Hilfe bei ner SCL -> AWL Übersetzung :-)



## kai86 (24 März 2010)

Hallo kenne mich mit AWL nicht ganz so gut aus, ich programmiere lieber in SCL, aber ich darf nun aus SCL-Code AWL-Code machen 

Habe was im Internet gefunden was etwas geholfen hat, aber so ganz passt das alles noch nicht. Also hier mein SCL und mein bisheriger AWL-Code


```
FUNCTION DCI_SendMessages: VOID    

BEGIN
NETWORK
TITLE =   DCI_SendMessages

U        DCI_Messages.MatReceivedFLAG
NOT

SPB        els1

Call DCI_STARTEVENT(MessageID:=21)        

Call DCI_WRITEINTPARAM(    id    := 102,
                         val    := Data.PortID)

CALL DCI_WRITEINTPARAM(    id  := 103,
                         val : =Data.SlotID)        

Call DCI_WRITESTRINGPARAM(    id  :=202, 
                            val :=Data.MaterialID)

U        FALSE
DCI_MESSAGECOMPLETE        

L        FALSE
=         #DCI_Messages.MatReceivedFLAG

els1:
end1:

U        DCI_Messages.MatRemovedFLAG
NOT

SPB        els2

L        22
DCI_STARTEVENT        

L        102
DCI_WRITEINTPARAM        DATA.PortID

L        103
DCI_WRITEINTPARAM        DATA.SlotID

L        202
DCI_WRITESTRINGPARAM        DATA.MaterialID

U        FALSE
DCI_MESSAGECOMPLETE        

U        FALSE
=         #DCI_Messages.MatRemovedFLAG

els2:
end2:
END_FUNCTION
```
So hier noch der SCL Code.


```
//File: DCI_SendMessages.scl
FUNCTION DCI_SendMessages:VOID
IF DCI_Messages.MatReceivedFLAG THEN
    DCI_StartEvent(MessageID:=21);
    DCI_WriteIntParam(id:=102, val:=Data.PortID);
    DCI_WriteIntParam(id:=103, val:=Data.SlotID);
    DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
    DCI_MessageComplete();
    DCI_Messages.MatReceivedFLAG:=False;
END_IF;

IF DCI_Messages.MatRemovedFLAG THEN
    DCI_StartEvent(MessageID:=22);
    DCI_WriteIntParam(id:=102, val:=Data.PortID);
    DCI_WriteIntParam(id:=103, val:=Data.SlotID);
    DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
    DCI_MessageComplete();
    DCI_Messages.MatRemovedFLAG:=False;
END_IF;

END_FUNCTION
```
dürfte ja eigentlich nicht so schwer sein oder?


----------



## vierlagig (24 März 2010)

was auch immer du vor hast...

in SCL proggen, übersetzen, Quelle aus dem Projekt entfernen, fertig ist der sehr leserliche AWL-code


----------



## kai86 (24 März 2010)

für mich ist der absolut nicht leserlich  hab das auch schon getestet.
Ok was ich vor habe. Ich generiere zur Zeit Code-Files aus einer Excel-Tabelle dies aber nur in SCL, dass kann aber nunmal nicht jeder übersetzen, deshalb will ich nun auch AWL-Code Files generieren. und dazu muss ich wissen wie ich IF s usw. in AWL bauen kann.

Grüße Kai


----------



## vierlagig (24 März 2010)

kai86 schrieb:


> und dazu muss ich wissen wie ich IF s usw. in AWL bauen kann.


 

```
*
      U     #myCase
      SPBN  else
      //hier IF
      SPA   end
else: //hier else
end:  NOP   0
```
 
usw.??


----------



## kai86 (24 März 2010)

Ok mal auf meinen Code angewendet:

```
U     #DCI_Messages.MatReceivedFLAG      
      SPBN  else
      CALL DCI_StartEvent(MessageID:=22);
      CALL DCI_WriteIntParam(id:=102, val:=Data.PortID);
      CALL DCI_WriteIntParam(id:=103, val:=Data.SlotID);
      CALL DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
      CALL DCI_MessageComplete();
      U FALSE
      = #DCI_Messages.MatRemovedFLAG
      SPA   end
else: //hier else
end:  NOP   0
```

Ist das so richtig? AWL ist halt etwas fremd für mich


----------



## vierlagig (24 März 2010)

kai86 schrieb:


> Ok mal auf meinen Code angewendet:


 
wenn du kein ELSE brauchst, kannste auch direkt zu end springen und dir das SPA sparen


----------



## kai86 (24 März 2010)

FUNCTION DCI_SendMessages: VOID	

BEGIN
NETWORK
TITLE =   DCI_SendMessages

U     #DCI_Messages.MatReceivedFLAG      
      SPBN  else
      CALL DCI_StartEvent(MessageID:=22);
      CALL DCI_WriteIntParam(id:=102, val:=Data.PortID);
      CALL DCI_WriteIntParam(id:=103, val:=Data.SlotID);
      CALL DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
      CALL DCI_MessageComplete();
      U FALSE
      = #DCI_Messages.MatRemovedFLAG
end:  NOP   0

U     #DCI_Messages.MatRemovedFLAG       
      SPBN  else
      CALL DCI_StartEvent(MessageID:=22);
      CALL DCI_WriteIntParam(id:=102, val:=Data.PortID);
      CALL DCI_WriteIntParam(id:=103, val:=Data.SlotID);
      CALL DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
      CALL DCI_MessageComplete();
      U FALSE
      = #DCI_Messages.MatRemovedFLAG
end:  NOP   0

END_FUNCTION


----------



## kai86 (24 März 2010)

das sollte jetzt stimmen oder muss der NOP nur am ende vom ganzen AWL-Code?


----------



## vierlagig (24 März 2010)

kai86 schrieb:


> das sollte jetzt stimmen oder muss der NOP nur am ende vom ganzen AWL-Code?


 
du kannst

a) die selbe marke, in deinem fall "end" nicht zweimal verwenden und
b) das NOP 0 auch nur einmal schreiben, wenn du von der ersten IF in die nächste IF springst ...

NOP 0 ist eine nulloperation, die man benutzt um lücken zu füllen. ich würde sie z.B. drinnen lassen um der übersichtlichkeit genüge zu leisten


----------



## kai86 (24 März 2010)

Also erstmal danke Vierlagig :-D

```
FUNCTION DCI_SendMessages: VOID	

BEGIN
NETWORK
TITLE =   DCI_SendMessages

U     #DCI_Messages.MatReceivedFLAG      
      SPBN  else
      CALL DCI_StartEvent(MessageID:=22);
      CALL DCI_WriteIntParam(id:=102, val:=Data.PortID);
      CALL DCI_WriteIntParam(id:=103, val:=Data.SlotID);
      CALL DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
      CALL DCI_MessageComplete();
      U FALSE
      = #DCI_Messages.MatRemovedFLAG
end1:  NOP   0

U     #DCI_Messages.MatRemovedFLAG       
      SPBN  else
      CALL DCI_StartEvent(MessageID:=22);
      CALL DCI_WriteIntParam(id:=102, val:=Data.PortID);
      CALL DCI_WriteIntParam(id:=103, val:=Data.SlotID);
      CALL DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
      CALL DCI_MessageComplete();
      U FALSE
      = #DCI_Messages.MatRemovedFLAG
end2

END_FUNCTION
```

Mal noch 2 Fragen, warum muss das else nicht unterschiedlich sein? Ist ja bestimmt kein befehlt oder? Und woher weiß das SPBN wo es hinspringen muss, wann sag ich dem das es zu end muss?


----------



## vierlagig (24 März 2010)

kai86 schrieb:


> Mal noch 2 Fragen, warum muss das else nicht unterschiedlich sein? Ist ja bestimmt kein befehlt oder? Und woher weiß das SPBN wo es hinspringen muss, wann sag ich dem das es zu end muss?


 
och kleener, so wird das nichts.
das LABEL, also "endx" und "elsy" *muss* eindeutig sein, für jede einzelne IF-THEN-ELSE-Dingens ... also, hast du z.B. drei dieser Konstrukte bietet sich: SPBN end1, SPBN end2, SPBN end3 an...


----------



## kai86 (24 März 2010)

Sags doch gleich 
Habe mich schon gewundert woher die das wissen ^^


```
FUNCTION DCI_SendMessages: VOID	

BEGIN
NETWORK
TITLE =   DCI_SendMessages

U     #DCI_Messages.MatReceivedFLAG      
      SPBN if1
      CALL DCI_StartEvent(MessageID:=22);
      CALL DCI_WriteIntParam(id:=102, val:=Data.PortID);
      CALL DCI_WriteIntParam(id:=103, val:=Data.SlotID);
      CALL DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
      CALL DCI_MessageComplete();
      U FALSE
      = #DCI_Messages.MatRemovedFLAG
if1:  NOP   0

U     #DCI_Messages.MatRemovedFLAG       
      SPBN if2
      CALL DCI_StartEvent(MessageID:=22);
      CALL DCI_WriteIntParam(id:=102, val:=Data.PortID);
      CALL DCI_WriteIntParam(id:=103, val:=Data.SlotID);
      CALL DCI_WriteStringParam(id:=202, val:=Data.MaterialID);
      CALL DCI_MessageComplete();
      U FALSE
      = #DCI_Messages.MatRemovedFLAG
if2

END_FUNCTION
```

So jetzt stimmts aber oder? wenn nicht ist AWL doof


----------



## vierlagig (24 März 2010)

kai86 schrieb:


> So jetzt stimmts aber oder?


 
if2 muß noch abgeschlossen werden



kai86 schrieb:


> wenn nicht ist AWL doof


 
AAAAAAAAAAALTER, DEINE MUTTER!


----------



## kai86 (24 März 2010)

Wenn du sagst if2 muss noch abgeschlossen werden meinst du was damit???
if2: NOP???
Ich kenne mich mit AWL wirklich so gut wie gar nicht aus. Du sprichst für mich immer in rätseln


----------



## vierlagig (24 März 2010)

genau das mein ich ... jedes label brauch ein : und eine anweisung dahinter, sonst wird es nicht übersetzt


----------



## kai86 (24 März 2010)

achso und wenn ich keine Anweisung habe schreibe ich einfach NOP da passiert dann halt nix. Ok danke für deine kurze einführung in AWL. falls ich nochmal ne frage dazu habe kommt die sicher demnächst hier rein ^^


----------



## kai86 (24 März 2010)

Ok habs eben mal übersetzt es kommen 40 fehler.
Ich vermute mal ich muss noch was mit den Symbolen machen, weil da meckert der aber wie muss das aussehen?


```
(*File: DCI_SendMessages.AWL*)
(*Version: 1.0*)

FUNCTION DCI_SendMessages:VOID
NAME:     DCI_SMsg
FAMILY:   SCL
AUTHOR:   ICH
VERSION:  0.1
KNOW_HOW_PROTECT
Begin
NETWORK
Title = DCI_SendMessages

U     #DCI_Messages.FLAGMatRecv
SPBN  if1
  CALL DCI_StartEvent(MessageID:=500);
  CALL DCI_WriteStringParam(id:=100, val:=Data.MaterialID);
  CALL DCI_WriteIntParam(id:=101, val:=Data.InPort);
  CALL DCI_MessageComplete();
  U FALSE
  = #DCI_Messages.FLAGMatRecv
if1:  NOP   0

U     #DCI_Messages.FLAGProcStart
SPBN  if2
  CALL DCI_StartEvent(MessageID:=502);
  CALL DCI_WriteStringParam(id:=100, val:=Data.MaterialID);
  CALL DCI_WriteStringParam(id:=103, val:=Data.RecipeID);
  CALL DCI_MessageComplete();
  U FALSE
  = #DCI_Messages.FLAGProcStart
if2:  NOP   0

U     #DCI_Messages.FLAGProcFin
SPBN  if3
  CALL DCI_StartEvent(MessageID:=505);
  CALL DCI_WriteStringParam(id:=100, val:=Data.MaterialID);
  CALL DCI_WriteRealParam(id:=301, val:=Data.Temperature);
  CALL DCI_WriteIntParam(id:=302, val:=Data.Pressure);
  CALL DCI_WriteBoolParam(id:=303, val:=Data.ProcessResult);
  CALL DCI_MessageComplete();
  U FALSE
  = #DCI_Messages.FLAGProcFin
if3:  NOP   0

U     #DCI_Messages.FLAGMatRem
SPBN  if4
  CALL DCI_StartEvent(MessageID:=508);
  CALL DCI_WriteStringParam(id:=100, val:=Data.MaterialID);
  CALL DCI_WriteIntParam(id:=102, val:=Data.OutPort);
  CALL DCI_MessageComplete();
  U FALSE
  = #DCI_Messages.FLAGMatRem
if4:  NOP   0

END_FUNCTION
```


----------



## vierlagig (24 März 2010)

die lokalen variablen

#DCI_Messages.FLAGMatRecv
#DCI_Messages.FLAGProcStart
#DCI_Messages.FLAGProcFin
#DCI_Messages.FLAGMatRem

sind doch gar nicht angelegt.
oder sind es womöglich globale variablen? dann ohne # und in der Symboltabelle anlegen.


----------



## kai86 (24 März 2010)

die sind global in nem DB namens DCI_Messages, welcher auch in der Symboltabelle so steht. Ohne # sinds trotzdem noch 40 Fehler.

der erste bei: SPBN  if1
mit der meldung syntaxfehler
der nächste ist Typkonflikt für DCI_Messages


----------



## kai86 (24 März 2010)

kann es sein das überall noch ein Strichpunkt dahinter muss


----------



## vierlagig (24 März 2010)

kai86 schrieb:


> kann es sein das überall noch ein Strichpunkt dahinter muss



wenn es ne quelle darstellen soll, dann ja...
und ohne #, stattdessen mit ""


----------



## kai86 (24 März 2010)

So nur noch 4 Fehler siehe Bild wie bekomme ich die noch weg 

wie muss das vielleicht liegts noch daran?

""DCI_Messages.FLAGMatRecv;
"DCI_Messages".FLAGMatRecv;
DCI_Messages."FLAGMatRecv";
"DCI_Messages.FLAGMatRecv";


----------



## Larry Laffer (24 März 2010)

mach mal aus deinem "U False" ein "CLR" ...
AWL kennt FALSE nicht als Operator.
Gruß
LL


----------



## kai86 (24 März 2010)

es kommt der selbe Fehler


----------



## vierlagig (24 März 2010)

Larry Laffer schrieb:


> mach mal aus deinem "U False" ein "CLR" ...
> AWL kennt FALSE nicht als Operator.
> Gruß
> LL



kennt es wohl, zumindest als ich noch programmiert habe 

und: "datenbausteinsymbol".datenbausteinbit ... die variante, die du nicht aufgeführt hast


----------



## kai86 (24 März 2010)

sorry mein fehler, es kommt kein fehler wenn mans richtig macht ^^ danke schön


----------



## Larry Laffer (24 März 2010)

was war nun der Fehler ?


----------



## kai86 (24 März 2010)

schon das mit dem u False durch clr ersetzen habs nur beim ersten mal false drin gelassen  versehentlich und dann zu schnell geantwortet mal sehen obs nun genauso geht wie der scl code


----------



## Larry Laffer (24 März 2010)

vierlagig schrieb:


> kennt es wohl, zumindest als ich noch programmiert habe


 
Du kannst False an den IN-Parameter eines FC's schreiben, wenn er vom Typ Bool ist - aber nicht "U False" als Programmcode (außer in SCL) - außer False ist ein symbolischer Operant ...

Gruß
LL


----------



## kai86 (25 März 2010)

Ok, dass muss ich noch, ich habe es mal so gemacht wie ich es mir gedacht habe, aber das sind sachen drin die ich noch nicht kenne. könnt ihr mir nochmal helfen will den code oben wieder übersetzen in awl.

```
VAR_TEMP
  VarInt1 : INT;
  VarInt2 : INT;
  VarString1 : STRING;
  VarString2 : STRING;
END_VAR

VarString1 := '';
VarString2 := '';

IF (DCI_Command.existent) THEN
  DCI_Command.handled := FALSE;

  IF (DCI_Command.MessageID = 777) THEN
      DCI_Command.handled := TRUE;
      DCI_GetStringParam(id:=100,s:=VarString1);
      DCI_GetStringParam(id:=103,s:=VarString2);
      IF (DCI_Command.isOK) THEN
         Data.MaterialID := VarString1;
         Data.RecipeID := VarString2;
      END_IF;
  END_IF;

  IF (DCI_Command.MessageID = 778) THEN
      DCI_Command.handled := TRUE;
      DCI_GetStringParam(id:=100,s:=VarString1);
      VarInt1 := DCI_GetIntParam(101);
      VarInt2 := DCI_GetIntParam(102);
      DCI_GetStringParam(id:=103,s:=VarString2);
      IF (DCI_Command.isOK) THEN
         Data.MaterialID := VarString1;
         Data.InPort := VarInt1;
         Data.OutPort := VarInt2;
         Data.RecipeID := VarString2;
      END_IF;
  END_IF;

END_IF;
END_FUNCTION
```
AWL übersetzung meinerseits 

```
AR_TEMP             
  VarInt1 : INT;
  VarInt2 : INT;
  VarString1 : STRING;
  VarString2 : STRING;
END_VAR

Begin
NETWORK
Title = DCI_HandleCommand


VarString1 := '';
VarString2 := '';


U     DCI_Command.existent;
SPBN  if1;
  CLR;
  = DCI_Command.handled;
  L DCI_Command.MessageID
  L 777
  ==m1.1
  SPBN  if2;    
    set;
    DCI_Command.handled;
    CALL DCI_GetStringParam(id:=100,s:=VarString1);
    CALL DCI_GetStringParam(id:=103,s:=VarString2);
    U DCI_Command.isOK
    SPBN  if3;    
        Data.MaterialID := VarString1;
        Data.RecipeID := VarString2;
    if3:  NOP   0;
  if2:  NOP   0;
if1:  NOP   0;
END_FUNCTION
```


----------



## vladi (25 März 2010)

*Awl..*

Hi,


```
VarString1 := '';
VarString2 := '';
```

das geht so nicht in AWL. Grundsätzlich: die SPS hat die Laderegister(Akku's),
damit u.a. werden die Befehle abgearbeitet. Die Register sind 32 Bit lang.
Eine Stringvariable ist mehrere Bytes breit. In AWL kann man mit Laden/Transferieren aber nur 4 Bytes(also 4 Zeichen) bearbeiten!
Eine Stringvariable ganz mit '' füllen bedeutet:entweder mittels einer Schleife alle Bytes initialisieren, oder eine bibl.Funktion benutzen, wie Block Move oder so.

Wie schon vierlagig sagte, es ist interessant, sich die Übersetzung vom SCL Compiler als rein AWL anzuschauen, dann sieht man Einiges.

V.


----------



## kai86 (25 März 2010)

Das kommt bei der Siemens übersetzung raus, aber ich hätte es gern schöner 


```
SET   
      SAVE  
      =     L    516.1
      L     W#16#FE00
      T     LW     4
      L     W#16#FE00
      T     LW   260
      U     "DCI_COMMAND".existent
      SPBN  A7d0
      CLR   
      =     DBX   28.0
      L     DBD   10
      L     DW#16#309
      ==D   
      SPBN  A7d1
      SET   
      =     DBX   28.0
      L     DW#16#64
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000020
      T     LD   524
      UC    "DCI_GetStringParam"
            P#L 518.0
            P#L 522.0
      L     DW#16#67
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000820
      T     LD   524
      UC    "DCI_GetStringParam"
            P#L 518.0
            P#L 522.0
      U     DBX   20.0
      SPBN  A7d1
      L     DW#16#10130001
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000020
      T     LD   524
      L     B#16#10
      AUF   DI   803
      T     DIB    4
      L     DW#16#10130001
      T     LD   528
      L     W#16#323
      T     LW   532
      L     DW#16#84000020
      T     LD   534
      UC    "BLKMOV"
            P#L 518.0
            P#L 542.0
            P#L 528.0
      L     DW#16#10130001
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000820
      T     LD   524
      L     B#16#10
      T     DIB   22
      L     DW#16#10130001
      T     LD   528
      L     W#16#323
      T     LW   532
      L     DW#16#840000B0
      T     LD   534
      UC    "BLKMOV"
            P#L 518.0
            P#L 546.0
            P#L 528.0
A7d1: L     "DCI_COMMAND".MessageId
      L     DW#16#30A
      ==D   
      SPBN  A7d0
      SET   
      =     DBX   28.0
      L     DW#16#64
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000020
      T     LD   524
      UC    "DCI_GetStringParam"
            P#L 518.0
            P#L 522.0
      L     DW#16#65
      T     LD   518
      UC    "DCI_GetIntParam"
            P#L 518.0
            P#L 0.0
      L     DW#16#66
      T     LD   518
      UC    "DCI_GetIntParam"
            P#L 518.0
            P#L 2.0
      L     DW#16#67
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000820
      T     LD   524
      UC    "DCI_GetStringParam"
            P#L 518.0
            P#L 522.0
      U     DBX   20.0
      SPBN  A7d0
      L     DW#16#10130001
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000020
      T     LD   524
      L     B#16#10
      AUF   DI   803
      T     DIB    4
      L     DW#16#10130001
      T     LD   528
      L     W#16#323
      T     LW   532
      L     DW#16#84000020
      T     LD   534
      UC    "BLKMOV"
            P#L 518.0
            P#L 550.0
            P#L 528.0
      L     #VarInt1
      T     DIW    0
      L     #VarInt2
      T     DIW    2
      L     DW#16#10130001
      T     LD   518
      L     W#16#0
      T     LW   522
      L     DW#16#87000820
      T     LD   524
      L     B#16#10
      T     DIB   22
      L     DW#16#10130001
      T     LD   528
      L     W#16#323
      T     LW   532
      L     DW#16#840000B0
      T     LD   534
      UC    "BLKMOV"
            P#L 518.0
            P#L 554.0
            P#L 528.0
A7d0: CLR   
      U     L    516.1
      SAVE  
      BE
```


----------



## Larry Laffer (25 März 2010)

... eine Stringbearbeitung wird in AWL nicht schön ... dazu ist dann SCL da ...
Vielleicht solltest du irgendwo mal eine Grenze ziehen - es geht doch (auch) um Übersichtlichkeit ...

Gruß
LL


----------



## kai86 (25 März 2010)

Jop SCL ist mir auch 1000mal lieber, aber wie gesagt es gibt manche die noch kein SCL haben, warum auch immer(wahrscheinlich zusatzkosten) und denen will ich dass jetzt in AWL aufbereiten. Will den Code selber generieren, dazu brauche ich was übersichtliches, was ich als AWL Quelle erstellen kann. Der erste Teil hat gut funktioniert. Nun fehlt nur noch dieser Code-Teil. Danach mache ich nie wieder was mit AWL  , hoffentlich


----------



## Larry Laffer (25 März 2010)

Na ... wenn das mal klappt ... 

Auf jeden Fall - das löschen eines Strings läßt sich durch Löschen der beiden Header-Bytes bewerkstelligen. Hierfür mußt du den String auf jeden Fall auf Byte-Ebene bearbeiten. Die im Inhalt ggf. noch stehenden Zeichen werden dann von weiteren Funktionen ignoriert.

Einen String in einen anderen übertragen wäre ein Fall für Blockmove oder eine selbsterstellte Schleife.

Für weitere Stringfunktionen kommen die gleichen FC's zum Einsatz, wie du sie auch in SCL verwendest - also LEFT, MID, RIGTH, CONCAT usw.

Gruß
LL


----------



## kai86 (25 März 2010)

Ich will die Strings am anfang ja nur initialisieren, gibt es da vielleicht auch was? oder muss ich die ersten beiden bytes löschen. wenn das nur damit geht, wie mache ich das?

L W#16#0;
T VarString1;

usw.?


----------



## kai86 (25 März 2010)

Ok sieht bisher so aus sind noch 8 fehler.

4 schonmal wegen meiner VarString aufrufe. aber warum???


```
VAR_TEMP             
  VarInt1 : INT;
  VarInt2 : INT;
  VarString1 : STRING;
  VarString2 : STRING;
END_VAR

Begin
NETWORK
Title = DCI_HandleCommand

L W#16#0000;
T #VarString1;
L W#16#0000;
T #VarString2;


U     DCI_Command.existent;
SPBN  if1;
  CLR;
  = DCI_Command.handled;
  L DCI_Command.MessageID;
  L 777;
  ==I;
  SPBN  if2;    
    set;
    = DCI_Command.handled;
    CALL DCI_GetStringParam(id:=dw#16#100,s:=VarString1);
    CALL DCI_GetStringParam(id:=dw#16#103,s:=VarString2);
    U DCI_Command.isOK;
    SPBN  if3;    
        UC BLKMOV(
            SRCBLK := #VarString1,
            DSTBLK := Data.MaterialID
        );
        UC BLKMOV(
            SRCBLK := #VarString2,
            DSTBLK := Data.RecipeID
        );
    if3:  NOP   0;
  if2:  NOP   0;
if1:  NOP   0;
END_FUNCTION
```


----------



## kai86 (25 März 2010)

Ok die 8 Fehler hängen alle mit den 4 VarString aufrufen zusammen. Also bitte helft mir  verzweifele sonst noch.


----------



## Larry Laffer (25 März 2010)

für das Init der Strings könnte das so aussehen :
	
	



```
L P##VarString_1
LAR1
L 0
T W [AR1,p#0.0]
```
für den Blockmove : ist denn dein Quell- und der Ziel-Bereich in der Größe identisch ?

Gruß
LL


----------



## kai86 (25 März 2010)

Also in SCL war das bisher immer egal. der Quell wurde an den Zielbereich angepasst ich hoffe das ist in AWL genauso. 
sind nur noch 4 Fehler die initialisierung scheint zu funktionieren.

wie löse ich das letzte problem mit dem BLKMOV


----------



## Larry Laffer (25 März 2010)

Larry Laffer schrieb:


> für den Blockmove : ist denn dein Quell- und der Ziel-Bereich in der Größe identisch ?


 
Aus deiner letzten Antwort schliesse ich, dass es bei dir nicht so ist ... dann wird es wohl nichts mit Blockmove - AWL ist DAS nicht egal ... 

Was willst du also tun ? Den Bereich anpassen oder einen eigenen Blockmove erstellen (so macht es SCL).

Gruß
LL


----------



## kai86 (25 März 2010)

Was verstehst du unter Bereich anpassen?
Und was unter eigenen Blockmove 

Sagen wir:
Quelle(String[254],mit 5 Zeichen also länge 5 im 2ten Byte)
Ziel(String[16], ich will alles rein kopieren und den rest abschneiden, also das erste byte verwerfen und das 2te byte mitkopieren)

ich hoffe ich habs gut erklärt


----------



## Larry Laffer (25 März 2010)

Ich hatte dich auch schon vorher verstanden.
Ein eigener Blockmove ist eine von dir erstellte Schleife, die deine Quelle in dein Ziel kopiert und die entsprechenden Anpassungen dann "handisch" vornimmt.
Sieh dir dazu vielleicht mal den entsprechenden Beitrag in der FAQ an ...


----------



## kai86 (25 März 2010)

welche FAQ, habe heute hier schon alles durchwühlt nach irgendwelchen hinweisen wie ich das mache 
aber ich gucke nochmal nach "eigenen BLKMOV".
mit dem normalen gehts dann also nicht so wie ich das will 
Habe ich das richtig verstanden


----------



## Larry Laffer (25 März 2010)

Mit FAQ meinte ich SPS-Forum\FAQ ...

schau doch einfach mal *hier*


----------



## kai86 (25 März 2010)

möglich das für welche die AWL oft nutzen die Codezeilen super leserlich sind aber ich muss mich da echt anstrengen 

Was ich machen muss ist ja nur lies byte 2 von Quelle und byte 1 von Ziel

schreibe b2.quelle nach b2.ziel
For n = inhalt.b2 +1  TO  b1.ziel
    lade b.quelle
    schreibe nach b.ziel
next n

wie mache ich das??? in AWL
frage mich warum awl heute noch genutzt wird. fub ok aber awl ist doch sinnlos ^^
helft mir, vielleicht bin ich auch zu scl verwöhnt.

ich schau mir so lange noch weiter den FAQ an vielleicht finde ich da doch noch die Lösung


----------



## Larry Laffer (25 März 2010)

Na ... du bist ja lustig ...
Wenn ich mich recht erinnere, dann wolltest du das in AWL machen - ich hatte dir empfohlen irgendwo einen Schlußstrich zu ziehen ... 

Es wird so gemacht, wie du es beschreibst :

```
-bilde Pointer auf Quell-Variable
-bilde Pointer auf Ziel-Variable
REPEAT
   -lese Byte an Position Quell-Pointer
   -schreibe Byte an Position Ziel-Pointer
   -erhöhe beide Pointer
   -erhöhe Index
UNTIL Index < Anzahl
```
... und jetzt viel Spaß ...


----------



## kai86 (25 März 2010)

Ok das kann ich so nicht machen wird zu umfangreich bei der Code generierung. ok dann habe ich nur noch die möglichkeit mit dem Blockmove.
wo liegt da jetzt der fehler? Quelle und Ziel sind von Byte 1 her gleich. Warum kommt da ein fehler? muss ich mir den anypointer selber zusammenbasteln? 


```
VAR_TEMP             
  VarInt1 : INT;
  VarInt2 : INT;
  VarString1 : STRING;
  VarString2 : STRING;
END_VAR

Begin
NETWORK
Title = DCI_HandleCommand

L P##VarString1;
LAR1;
L 0;
T W [AR1,p#0.0];
L P##VarString2;
LAR1;
L 0;
T W [AR1,p#0.0];


U     DCI_Command.existent;
SPBN  if1;
  CLR;
  = DCI_Command.handled;
  
  L DCI_Command.MessageID;
  L 777;
  ==D;
  SPBN  ig1;    
    set;
    = DCI_Command.handled;
    CALL DCI_GetStringParam(id:=dw#16#100,s:=VarString1);
    CALL DCI_GetStringParam(id:=dw#16#103,s:=VarString2);
    U DCI_Command.isOK;
    SPBN  ih1;    
        AUF 
        UC BLKMOV(
            SRCBLK := VarString1,
            DSTBLK := Data.MaterialID
        );
        UC BLKMOV(
            SRCBLK := VarString2,
            DSTBLK := Data.RecipeID
        );
    ih1:  NOP   0;
  ig1:  NOP   0;
  
  L DCI_Command.MessageID;
  L 778;
  ==D;
  SPBN  ig2;    
    set;
    = DCI_Command.handled;
        Call DCI_GetIntParam(id:=dw#16#101,RET_VAL:=VarInt1);
        Call DCI_GetIntParam(id:=dw#16#102,RET_VAL:=VarInt2);
    U DCI_Command.isOK;
    SPBN  ih2;
        L VarInt1;
        T Data.InPort;
        L VarInt2;
        T Data.OutPort;
    ih2:  NOP   0;
  ig2:  NOP   0;
  
if1:  NOP   0;
END_FUNCTION
```


----------



## kai86 (25 März 2010)

OK nun kommen zumindest keine Fehler mehr.
mal sehen obs halbwegs geht, dass reicht mir 


```
FUNCTION DCI_HandleCommand:VOID

VAR_TEMP
  iERROR  : INT;             
  VarInt1 : INT;
  VarInt2 : INT;
  VarString1 : STRING;
  VarString2 : STRING;
END_VAR

Begin
NETWORK
Title = DCI_HandleCommand

L P##VarString1;
LAR1;
L W#16#FE00;
T W [AR1,p#0.0];
L P##VarString2;
LAR1;
L W#16#FE00;
T W [AR1,p#0.0];


U     DCI_Command.existent;
SPBN  if1;
  CLR;
  = DCI_Command.handled;
  
  L DCI_Command.MessageID;
  L 777;
  ==D;
  SPBN  ig1;    
    set;
    = DCI_Command.handled;
    CALL DCI_GetStringParam(id:=dw#16#100,s:=VarString1);
    CALL DCI_GetStringParam(id:=dw#16#103,s:=VarString2);
    U DCI_Command.isOK;
    SPBN  ih1;    
        Call "BLKMOV"(
            SRCBLK := VarString1,
            RET_VAL := iERROR,
            DSTBLK := Data.MaterialID
        );
        Call "BLKMOV"(
            SRCBLK := VarString2,
            RET_VAL := iERROR,
            DSTBLK := Data.RecipeID
        );
    ih1:  NOP   0;
  ig1:  NOP   0;
  
  L DCI_Command.MessageID;
  L 778;
  ==D;
  SPBN  ig2;    
    set;
    = DCI_Command.handled;
        Call DCI_GetIntParam(id:=dw#16#101,RET_VAL:=VarInt1);
        Call DCI_GetIntParam(id:=dw#16#102,RET_VAL:=VarInt2);
    U DCI_Command.isOK;
    SPBN  ih2;
        L VarInt1;
        T Data.InPort;
        L VarInt2;
        T Data.OutPort;
    ih2:  NOP   0;
  ig2:  NOP   0;
  
if1:  NOP   0;
END_FUNCTION
```


----------



## Larry Laffer (25 März 2010)

Es liegt erstmal gar nicht an den unterschiedlichen Strings ...

Du hast in deinem Baustein ein AUF stehen - AUF was ? Dieser Befehl ruft einen DB auf : also AUF DB10 (z.B.)

Dann der Aufruf des Blockmove - mach das mal so :
	
	



```
Call "BLKMOV"(
            SRCBLK := VarString1,
            RET_VAL := mw200,
            DSTBLK := Data.MaterialID
```
Gruß
LL

Nachsatz:
Oh ... ich sehe gerade, dass du das mittlerweile selbst herausgefunden hast ...


----------



## kai86 (25 März 2010)

habs schon gefunden siehe beitrag vor dir 

muss ich den DB nun aufmachen wie es in der einen beschreibung steht? ne oder? macht sicher der BLKMOV für mich.

Grüße kai


----------



## kai86 (25 März 2010)

Ok der generator funktioniert so wie er soll danke  was ich als einzigstes noch machen muss ist das mit der Stringgröße, weil die mitübertragen wird, aber da habe ich schon eine idee 

Grüße Kai


----------



## kai86 (25 März 2010)

Ok brauche doch noch einmal eure Hilfe.

ich will folgendes machen.
String[254]     Data.Str[16]

Quelle=String,Ziel=Data.Str

merke das erste Byte von Data.Str
mache BLKMOV
schreibe Byte zurück an erste Stelle von Data.Str
so geht der Header nicht verloren. 
Wie geht das vor und nach BLKMOV

L B P#Data.Str
BLKMOV
T B P#Data.Str

sowas in der Richtung nur halt richtig


----------



## kai86 (26 März 2010)

Auch gut wäre erste Byte von Data.Str kopieren in erstes Byte VarString und dann den Blockmove machen, aber irgendwie kriege ich das erste byte von Data.Str nicht kopiert.


----------



## Larry Laffer (26 März 2010)

Hallo,
vielleicht ungefähr so :
	
	



```
L p##Data.Str
LAR1
L B [AR1,P#0.0]
T#mein_Temp_Byte
 
dein Blockmove
 
L p##Data.Str
LAR1
L #mein_Temp_Byte
T B [AR1,P#0.0]
```
Gruß
LL


----------



## kai86 (26 März 2010)

Habe ich auch schon versucht 
aber da kommen die Fehlermeldungen siehe Anhang.


----------



## vierlagig (26 März 2010)

kai86 schrieb:


> Habe ich auch schon versucht
> aber da kommen die Fehlermeldungen siehe Anhang.



da fehlt ein leerzeichen hinter T


----------



## dalbi (26 März 2010)

Hi,

das geht so nicht Du kannst nur schreiben P##Data, zugriff auf Strukturen ist damit nicht möglich. Du kannst aber zu AR1 entsprechend eine Offset addieren.

Gruss Daniel


----------



## kai86 (26 März 2010)

und wie komme ich dann zu dem Byte? Bzw. wie meinst du das mit dem Offset


----------



## dalbi (26 März 2010)

```
L P##Data
LAR1
L B[AR1, P#10.0]
T #saveHeader
```

wäre z.B. das Byte 10 nach der Adresse von Data

oder zu AR1 den Offset addieren

```
L P##Data
LAR1
+AR1 P#10.0
L B[AR1, P#0.0]
T #saveHeader
```

Gruss Daniel


----------



## kai86 (26 März 2010)

mein Problem ist ich kenne den Offset nicht, zu diesem Zeitpunkt. Ich weiß nicht wo mein string in dem DB steht.


----------



## Larry Laffer (26 März 2010)

... aber du weißt doch, wo sich Str in Beziehung zu Data befindet.

Anmerkung:
Das mit der Struktur hatte ich überhaupt nicht realisiert ...


----------



## kai86 (26 März 2010)

nein das eben nicht ich weiß ich habe einen DB Data und irgendwo darin ist der String an welcher stelle, habe ich keine ahnung. das muss doch gehen 
dachte das wäre ne gute möglichkeit um das mit dem selbstgeschriebenen Blockmove zu umgehen. ich muss möglichst wenig Programm-Code haben.


----------



## Larry Laffer (26 März 2010)

Hallo ...?
Wenn du mit einer Struktur arbeitest, so ist deren Aufbau schon vorher festgelegt - deren Aufbau ändert sich zur Laufzeit nicht. Nicht einmal die Position von Data (also der Struktur) ist im DB variabel - auch diese Position ist schon (von dir) festgelegt. Step7 arbeitet hier nur augenscheinlich mit variablen Adressen.


----------



## kai86 (26 März 2010)

ich weiß, da ich aber einen Code generiere und ich dafür nur die Symbolischen Namen bekomme, kann ich unmöglich die festen dbs wissen.


----------



## Larry Laffer (26 März 2010)

Ich glaube, wir reden aneinander vorbei ...

Solange, wie du mit symbolischen Operanden arbeitest ist die Adresse desselben IMMER fest vergeben. Etwas anderes wäre es, wenn du dir für irgend etwas einen Pointer zusammenbasteln würdest (aber das tust du ja nicht) - dann wäre aber ein symbolischer Zugriff nicht mehr machbar.

Das Arbeiten mit Pointern in diesem (jetzigen) Zusammenhang findet nur deshalb statt, damit du nicht immer alle Adressen neu (selbst) erstellen mußt, wenn du mal irgendwo eine Variable dazwischen baust. Dein ganzes Programm könnte aber auch komplett aus absoluten Zugriffen bestehen und würde auch funktionieren. Letztlich werden im MC7-Code aus Allem absolute Zugriffe gemacht ...


----------



## kai86 (26 März 2010)

Hallo, die Adresse ist fest vergeben ok, aber ich kenne sie nicht, dass will ich damit sagen. ich kenne nur den Symbolnamen. Data.Str wo der "Str" in Data steht weiß ich allerdings nicht da ich nur den Symbolnamen kenne 
ich weiß nicht ob du das verstehst was ich sagen will.

also wenn ich nicht lesend auf db zugreifen kann muss ich wirklich byte für byte kopieren. ich versuche mal zu testen wieviel codeunterschied das macht


----------



## dalbi (26 März 2010)

Hi,

warum muss das unbedingt mit AWL gemacht werden? Bei so etwas ist SCL einfach Klasse.

Gruss Daniel


----------



## kai86 (26 März 2010)

in scl geht es schon, aber viele haben kein scl und für die mache ich das nun in awl. klappt ja auch soweit bis auf die doofen strings


----------



## vierlagig (26 März 2010)

kai86 schrieb:


> in scl geht es schon, aber viele haben kein scl und für die mache ich das nun in awl. klappt ja auch soweit bis auf die doofen strings



prog es mal in SCL und schau dir den generierten AWL-code an ...


----------



## kai86 (26 März 2010)

habe ich schon und ich habe den code auch schon hier gepostet.


----------



## vierlagig (26 März 2010)

kai86 schrieb:


> habe ich schon und ich habe den code auch schon hier gepostet.



wo? verlink mal den beitrag, der thread ist ja schon unübersichtlich...


----------



## kai86 (26 März 2010)

Seite 3 und Beitrag #30 der SCL Code
Seite 4 und Beitrag #32 der von Step7 generierte AWL Code


----------



## Larry Laffer (26 März 2010)

@4L und Dalbi:
ich verstehe den Sinn der Übung auch nicht, aber seine Source ist schon SCL - es soll halt nun ein direkt in AWL erstellter Code nachkommen. Ich hatte es auch schon geschrieben : man muß sich nicht jeden Spaß gönnen ... aber ihr wißt ja : des Menschen Wille ist sein Himmelreich ... 

@Kai:
Mir ist schon klar, dass du die Position des Struct's nicht kennst (willst) - wohl aber dessen Aufbau. In diesem VORGEGEBENEN Aufbau befindet sich das Unter-Element an einer bestimmten Stelle. Diese mußt du direkt ansprechen. Änderst du den Struct, so mußt du das dann natürlich nachpflegen. Das würde in SCL aber genauso gelten (dort müßtest du dann neu übersetzen - wenigstens).


----------



## kai86 (26 März 2010)

der Strukt ändert sich nie aber ich komme doch auch nicht lesend an das 2te Byte oder? 

Also für alle die neu sind 

es geht gerade nur noch darum das mir der Blkmov das erste Byte des Headers mit kopiert, ich das aber nicht will. Falls da von euch noch ideen kommen ich weiß nicht was in awl so möglich ist.


----------



## vierlagig (26 März 2010)

kai86 schrieb:


> der Strukt ändert sich nie aber ich komme doch auch nicht lesend an das 2te Byte oder?



wenn das struCt immer gleich bleibt dann kommst du mit von dalbi angesprochenen offset eben genau an das zweite byte... sogar schreibend


----------



## kai86 (26 März 2010)

Woher weiß der Pointer wo Data.Str der Str anfängt? auch wenns immer gleich bleibt kenne ich den String anfang nicht. Oder wie meint ihr das? stehe ich gerade nur aufm schlau?

```
L P##Data
LAR1
L B[AR1, P#10.0]
T #saveHeader
```


----------



## dalbi (26 März 2010)

Hi,

ohne jetzt groß hier umeinander zu schreiben, zeige doch bitte mal Deine Deklarationen der Variablen von dem Baustein?

Gruss Daniel


----------



## kai86 (26 März 2010)

Das ist das Problem ihr denkt ich habe einen festen baustein. Das problem ist das ich einen codegenerator habe dieser wird nur mit den Symbolnamen gefüttert und der generiert awl code. da es für verschiedene anwender ist kann ich vorher noch nicht sagen was der in seinem db drin stehen hat. deswegen bringt es gar nichts wenn ich jetzt meinen db zeige mit den db adressen.
wichtig ist der hat nen symbolnamen und mehrere Variablen drin deren typen bekannt sind aber in welcher reihenfolge ist auch nicht klar.
ich hoffe das war verständlich. 
ich weiß nicht wie ich es sonst noch beschreiben soll.


----------



## dalbi (26 März 2010)

Hi,

P##Data ist doch kein DB?

Gruss Daniel


----------



## kai86 (26 März 2010)

ja das ist ein pointer auf den DB "Data"


----------



## dalbi (26 März 2010)

Bitte zeige doch einfach mal die Struktur von Data.

Gruss Daniel


----------



## dalbi (26 März 2010)

Also ist Data ein IN vom Typ Pointer oder wie?

Gruss Daniel


----------



## kai86 (26 März 2010)

im anhang, ist der Beispiel Datenbaustein


----------



## dalbi (26 März 2010)

Links stehen die Adressen also für die aktuelle Stringlänge vom ersten String wäre es z.B. B[AR1,P#7.0] bezogen auf Data.

Gruss Daniel


----------



## kai86 (26 März 2010)

ich wußte das du darauf hinaus willst 
aber das geht nicht weil ich die ja normalerweise nicht weiß. wie gesagt ich generiere den Code mit nem makro und spiele den dann einfach ein und da sind keine db nummern bekannt nur die symbole.


----------



## dalbi (26 März 2010)

Macht doch auch nichts, aber der DB ist doch immer gleich oder?

Gruss Daniel


----------



## dalbi (26 März 2010)

Ich meine nicht die DB Nummer sondern den Aufbau des DB's.

Gruss Daniel


----------



## kai86 (26 März 2010)

nein der ist von mal zu mal unterschiedlich mit ner unterschiedlichen anzahl an variablen


----------



## Larry Laffer (26 März 2010)

> nein der ist von mal zu mal unterschiedlich mit ner unterschiedlichen anzahl an variablen


 wie kriegst du das denn hin ?
Der Speicher der SPS ist nicht dynamisch ...


----------



## vierlagig (26 März 2010)

Larry Laffer schrieb:


> wie kriegst du das denn hin ?
> Der Speicher der SPS ist nicht dynamisch ...



naja, doch schon ein bißchen, aber das kommt hier sicher nicht zur anwendung...
fakt ist, dass aus der vorgegebenen struktur für die code-generierung der adressversatz berechnet werden muß PUNKT


----------



## dalbi (26 März 2010)

Vor allem wie übergibst Du "Data" was ist das, etwa das Symbol des DB's?

Gruss Daniel


----------



## kai86 (26 März 2010)

ihr seit alle noch nicht auf einer wellenlänge mit mir ^^ ok ich versuchs nochmal

ich habe ne excel tabelle, da werden alle betreffenden DBs sammt Varname eingetragen und noch paar andere sachen aber egal.


Data.Str
Data.str1
data.int1
data.real
data.irgendwas

in den Vars steht was drin was ich über tcp senden will. nun kann über ein makro ein code-file erstellt werden das mir eine art protokol zusammenbastelt und die variablen einbindet.

dem makro ist aber zu keinem zeitpunkt die DB-nummer und die interne verteilung bekannt. in scl ist das ja alles kein problem, aber da mir awl blockmove den header zerschießt ...


----------



## kai86 (26 März 2010)

ja Data ist das symbol des DBs dachte das sei klar


----------



## dalbi (26 März 2010)

Ok. Da kommst Du aber mit P##Data nicht ran. 

Gruss Daniel


----------



## Larry Laffer (26 März 2010)

kai86 schrieb:


> ihr seit alle noch nicht auf einer wellenlänge mit mir ^^ .


 
 ... oder du nicht mit uns ...
Ich denke, dass Dalbi dir die Lösung schon vor ca. 30 Beiträgen (mindestens) gesagt hat.


----------



## kai86 (26 März 2010)

@ dalbi ja genau, da ich aber bisher nur scl kenne und awl etwas fremd für mich ist, dachte ich ihr könnt mir helfen
@larry ich glaube das es noch nicht die lösung ist die ich suche


----------



## Larry Laffer (26 März 2010)

kai86 schrieb:


> ... in scl ist das ja alles kein problem, aber da mir awl blockmove den header zerschießt ...


Dann rette den vielleicht vor dem Blockmove und spiel ihn hinterher wieder rein --- das hatten wir aber auch schon gehabt (ist nur noch etwas länger her) ...


----------



## Larry Laffer (26 März 2010)

kai86 schrieb:


> ... und awl etwas fremd für mich ist, dachte ich ihr könnt mir helfen


 
Können wir nur, wenn du dir auch helfen lassen willst ...


----------



## kai86 (26 März 2010)

jop ich kann mich dran erinnern habs damit auch versucht bis zum umfallen, aber da ich nicht auf den DB zugreifen kann ...

glaub mir du verstehst nur noch nicht wie ich das meine  , glaube dalbi hats oder fast ^^

oder zeig mir wie ich den header rette und ich sage dir daran was ich nicht machen kann weil ich das nicht habe


----------



## Larry Laffer (26 März 2010)

Stellst du bitte mal deinen DB (von mir aus AWL-Quelle) hier ein ...


----------



## kai86 (26 März 2010)

der db ist schon drin als bild auf seite 9 oder 10 oder so


----------



## dalbi (26 März 2010)

Ja.

Du solltest Dein Konzept komplett überdenken.

Gruss Daniel


----------



## dalbi (26 März 2010)

> Gibt man einer Kuh das falsche Futter, wird's Margarine anstatt Butter.



So ähnlich ist das auch bei der SPS. 

Gruss Daniel


----------



## kai86 (26 März 2010)

ach ich lass es jetzt einfach so habt vielen dank für eure geduld, wenn  der Header kaputt geht muss halt jeder selbst den generierten code  nachpflegen, das wollte ich halt verhindern.
Aber ich glaube so viel aufwand ist das dann auch nicht mehr 

wäre schön gewesen.

ich bin mir sicher das eure codevorschläge alle funktionieren, aber  nicht in meinem fall.

Vielleicht noch ein letztes mal kurz.

ich habe ne funktion, darin wird ein string empfangen über ethernet der soll in einen DB geschrieben werden. der string wird erstmal in ner tempvariablen zwischengespeichert, dann soll die in den Datenblock "Data" geschrieben werden. und zwar an die stelle wo sich die variable "Str" befindet. ich weiß die nummern nicht und wie der DB aufgebaut ist weiß ich auch nicht ich kenne nur DATA und das darin irgendwo ein Str ist den ich beschreiben will. so besser kann ich es nicht erklären ^^


----------



## dalbi (26 März 2010)

Hi Kai,

das war doch auch nicht böse gemeint. Schreibe doch einfach in den Anfang des DBs (Variable) die Anfangsadresse des Strings, in deinem Programm liest Du die dann aus und generierst Dir daraus den Pointer.

Gruss Daniel


----------



## kai86 (26 März 2010)

hallo  ich habs auch nicht böse aufgefasst. 
Ich darf den DB auf die art nicht verändern. nur in die vorgegebenen bereiche schreiben. zudem muss ich auch gleichzeitig mehrere in data befindliche strings beschreiben. die auch wieder irgendwo darin sind. da bräuchte ich dann auch wieder die adresse


----------



## Paule (26 März 2010)

kai86 schrieb:


> Vielleicht noch ein letztes mal kurz.
> 
> ich habe ne funktion, darin wird ein string empfangen über ethernet der soll in einen DB geschrieben werden. der string wird erstmal in ner tempvariablen zwischengespeichert, dann soll die in den Datenblock "Data" geschrieben werden. und zwar an die stelle wo sich die variable "Str" befindet. ich weiß die nummern nicht und wie der DB aufgebaut ist weiß ich auch nicht ich kenne nur DATA und das darin irgendwo ein Str ist den ich beschreiben will. so besser kann ich es nicht erklären ^^


Ist das die gleiche Frage wie am Anfang?
Sorry, ich habe das Thema nicht mit verfolgt und möchte jetzt eigentlich nicht fast Hundert Beiträge durchlesen.

Aber für mich hört sich das so an also ob Du einfach einen Anyzeiger zerlegen musst um an die Daten zu kommen.
Aber so einfach wird es wohl nicht sein.


----------



## kai86 (26 März 2010)

wie machst du einen zeiger auf den DB von dem du nur die Symbolnamen kennst. hat bei mir nicht funktioniert aber vielleicht hast du ja jetzt die lösung.


----------



## dalbi (26 März 2010)

Moment, ich überlege mir mal was.

Ergebnis folgt in kürze. 

Du willst doch eigentlich nur einen String[254] in einen String[30] kopieren oder?

Gruss Daniel


----------



## kai86 (26 März 2010)

ja genau nur der string[254] hat 5 zeichen drin und der string[30] ist leer.
der String[30] will seine länge 30 aber auch nicht verlieren ^^ beim kopieren

BLKMOV macht mir den String[30] zu nem String[254]

hui wir sind langsam auf einer welle :-D


----------



## dalbi (26 März 2010)

Ok. Hab es mal getestet das stimmt.

Nun müssen wir nur noch unseren eigenen BLKMOV basteln.

Gruss Daniel


----------



## Paule (26 März 2010)

kai86 schrieb:


> wie machst du einen zeiger auf den DB von dem du nur die Symbolnamen kennst. hat bei mir nicht funktioniert aber vielleicht hast du ja jetzt die lösung.


Na so :

```
VAR_INPUT
      Daten : ANY
   END_VAR
 
   L P##Daten
   LAR1
```


----------



## kai86 (26 März 2010)

das hatte mir larry auch gesagt aber ich habs nicht geschafft, bin wie gesagt awl neuling. weiß zwar was ich haben will aber die umsetzung macht mir probleme ^^


----------



## Paule (26 März 2010)

OK, ich sehe schon da müsste ich erst alles durchlesen um nicht doppelte Antworten zu geben.
Ich klink mich da mal aus.

Aber bei Larry und Dalbi bist ja in guten Händen. 
Viel Erfolg noch.


----------



## dalbi (26 März 2010)

Hi,

so Kai, anbei die Quelle für das kopieren.


```
FUNCTION "CopyString" : VOID
TITLE =String kopieren
//Achtung! 
//Die maximale Stringlänge wird nicht berücksichtigt.
VERSION : 0.1


VAR_INPUT
  SRCBLK : ANY ;    
  DSTBLK : ANY ;    
END_VAR
VAR_TEMP
  tAnzahl : INT ;    
  tDstDBNr : WORD ;    
  tSrcDBNr : WORD ;    
  tZaehler : INT ;    
  tSaveAr1 : DWORD ;    
  tSaveAr2 : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =Adressregister sichern

      TAR1  #tSaveAr1; 
      TAR2  #tSaveAr2; 

NETWORK
TITLE =Zeiger zusammenstellen

      L     P##SRCBLK; 
      LAR1  ; 
      L     W [AR1,P#4.0]; //DB-Nummer o. =0
      T     #tSrcDBNr; 
      L     D [AR1,P#6.0]; //Speicherbereich
      LAR1  ; //AR1 auf Erste Adresse

      L     P##DSTBLK; 
      LAR2  ; 
      L     W [AR2,P#2.0]; //Wiederholfaktor
      T     #tAnzahl; 
      L     W [AR2,P#4.0]; //DB-Nummer o. =0
      T     #tDstDBNr; 
      L     D [AR2,P#6.0]; //Speicherbereich
      LAR2  ; //AR2 auf Erste Adresse

NETWORK
TITLE =Daten kopieren

      L     #tAnzahl; //Schleifenzähler initialisieren
      L     1; 
      -I    ; 
next: T     #tZaehler; 

      AUF   DB [#tSrcDBNr]; //Quelle Datenbaustein öffnen
      L     DBB [AR1,P#1.0]; //Quelle laden
      AUF   DB [#tDstDBNr]; //Ziel Datenbaustein öffnen
      T     DBB [AR2,P#1.0]; //Ziel transferieren

      +AR1  P#1.0; //Adresse AR1 um Byte erhöhen
      +AR2  P#1.0; //Adresse AR2 um Byte erhöhen

      L     #tZaehler; //Noch mal?
      LOOP  next; 

NETWORK
TITLE =Adressregister AR1&2 wiederherstellen

      LAR1  #tSaveAr1; 
      LAR2  #tSaveAr2; 

END_FUNCTION
```
Der Aufruf ist dann wie folgt

```
CALL  "CopyString"
       SRCBLK:="DB_Quelle".Str
       DSTBLK:="DB_Ziel".Str
```
Gruss Daniel


----------



## kai86 (26 März 2010)

ok danke für den Programm-Code das ist genau das was ich brauche nur sehr umfangreich ^^

aber wenn ich das einfach so vor mein Netzwerk packe sollte es ja kein problem sein  darauf bin ich noch gar nicht gekommen. danke hast mir sehr weitergeholfen.

danke danke danke


----------



## dalbi (26 März 2010)

Dann drück mal.

Gruss Daniel


----------



## Larry Laffer (26 März 2010)

@Daniel:
Schön gemacht ... ich hätte ihm allerdings keinen Copy-Baustein geschrieben ...


----------



## kai86 (26 März 2010)

gab fehler beim laufenden betrieb in der funktion. aber den finde ich schon noch alleine, besten dank auf jedenfall an alle. 

Grüße Kai


----------



## dalbi (26 März 2010)

In meiner Funktion? Der ist getestet und funktioniert.

Gruss Daniel


----------



## kai86 (26 März 2010)

kamen auch 5 warnungen. muss irgendein laufzeit konflikt sein vielleicht hat der irgendwas überschrieben was ich gerade verwende was weiß ich 

aber ich habe es mir auch noch nicht weiter angeschaut. stand halt fehler in der funktion als die aufgerufen wurde in zeile 76 oder so


----------



## Larry Laffer (27 März 2010)

dalbi schrieb:


> P##Data ist doch kein DB?
> 
> Gruss Daniel



Ich muss hier doch noch mal einhaken ...
"Data" ist ja nun doch der DB und wenn die Anwort bei dem betreffenden Beitrag richtig gekommen wäre, dann hätte man sich die eine oder andere Mühe sparen können. In einem SB kannst du natürlich die direkt (also außerhalb einer Struktur) angelegten Elemente auch ver-pointern. Das geht dann so :
	
	



```
L p##"Data".meinEintrag
```
vielleicht ist das jetzt auch der Grund, warum der Baustein von Daniel nicht nbei dir funktioniert ... 

Gruß
LL


----------



## dalbi (28 März 2010)

Hi Larry,

das ist leider nicht möglich, bzw. es wäre mir neu.

Gruss Daniel


----------

