# Pointer <- Indirekter DB möglich ?



## rs-plc-aa (22 März 2007)

Hallo,
ich bin gerade auf etwas gestossen...

Ich möchte dem Pointer  P#DB591.DBX 1200.0 BYTE 12  den DB über eine Variable mitteilen - geht das ?

Also z.B. so: P#DB[DB_Nr].DBX 1200.0 BYTE 12

... nur daß es halt so nicht geht  

Weiß jemand die korrekte Syntax ?


----------



## volker (22 März 2007)

ja, das geht. zwar nicht in dem format wir du das möchtetst.  das wäre ja zu einfach 

das zauberwort ist *any-zeiger*

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

auf meiner hp im forum in der faq findest du einen gute beschreibung dazu.
in der s7-hilfe wirst du aber auch fündig


----------



## rs-plc-aa (22 März 2007)

Wenn ich das richtig verstanden habe lege ich z.B. eine TEMP_VAR des Typs ANY an und füttere sie am Anfang des Bausteins wie in dem Beispiel, und setze dann die TEMP_VAR an den IN Parameter (anstatt des direkten Pointers) ?


----------



## volker (22 März 2007)

ja genau.

schau dir das ruhig mal auf meiner homepage an. ich habe das dort recht ausführlich beschrieben.


----------



## rs-plc-aa (22 März 2007)

volker schrieb:


> ja genau.
> 
> schau dir das ruhig mal auf meiner homepage an. ich habe das dort recht ausführlich beschrieben.


 
Sorry - ich find´s net...


----------



## rs-plc-aa (22 März 2007)

Habs immer noch nicht gefunden - aber mal so probiert:


```
L     W#16#1002                   // konstant gleich
      T     LW     0                    // Datentyp: INT
      L     12                          // konstant gleich
      T     LW     2                    // Datentyp: INT
      L     #DI_Number                  // IN (diesen möchte ich variabel haben)
      T     LW     4                    // Datentyp: INT
      L     1200                        // passend zu obigem Beispiel-Pointer
      SLD   3                           // ???
      OD    DW#16#84000000              // ??????
      T     LD     6                    // ?
```
 
Finde ich jetzt im VAR_TEMP -> Startadresse 0 meinen ersehnten ANY ?


----------



## rs-plc-aa (22 März 2007)

@Volker: Habs jetzt gefunden auf deiner Homepage...
Somit müsste mein voriger post eigentlich beantwortet sein.
Jetzt sind mir aber Unterschiede aufgefallen:

```
[FONT=Lucida Console][COLOR=#000000]-> L     B#16#10                   //10h für s7[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> T     LB     0[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> L     B#16#02                   //Typ BYTE[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> T     LB1     0[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]   L     8                         //Anzahl (Wiederholungsfaktor)[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]   T     LW     2[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]   L     33                        //Datenbaustein[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]   T     LW     4[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]   L     14                        //Anfangsadresse[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]   SLD   3                         //Pointer bauen[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]   T     LD     6[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> L     B#16#84                   //Speicherbereich (hier DB)[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> T     LB     6[/COLOR][/FONT]
```
Am Anfang und am Ende (mit Pfeilen markiert) ist das unterschiedlich - welche Version ist jetzt richtig (für eine S7-300) ?

(Ja ich weiß - man soll sich nicht selber antworten )


----------



## volker (22 März 2007)

rs-plc-aa schrieb:


> @Volker: Habs jetzt gefunden auf deiner Homepage...


na also. geht doch.  Und nicht vergessen: Beiträge bewerten (hier und auch auf meiner hp)


```
[FONT=Lucida Console][COLOR=#000000]-> L     B#16#10                   //10h für s7[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> T     LB     0[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> L     B#16#02                   //Typ BYTE[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> T     LB1     0[/COLOR][/FONT]
```
vom prinzip das gleiche wie L w#16#1002 nur dass du die bytes einzeln transferierst (linkes byte, rechtes byte des wortes)
so kannst du aber den typ leichter angeben.

```
[FONT=Lucida Console][COLOR=#000000]L     14                        //Anfangsadresse[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]SLD   3                         //Pointer bauen[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]T     LD     6[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> L     B#16#84                   //Speicherbereich (hier DB)[/COLOR][/FONT]
[FONT=Lucida Console][COLOR=#000000]-> T     LB     6[/COLOR][/FONT]
```
sieht ein bisschen komisch aus. hat aber durchaus seinen sinn.
du lädst den pointer in das ld 6. weil, dort gehört er hin.
der speicherbereich des anyzeigers liegt aber im LB 6 (bedenke: nur das byte) deshalb wird der vorige transfer teilweise durch diesen überschrieben.

```
(Ja ich weiß - man soll sich nicht selber antworten:) )
```
würde ICH so nicht sagen.
wenn du die lösung selbst gefunden hast, und die lösung hier präsentierst, müssen sich andere leute keine weiteren gedanken darüber machen und leute die evtl das gleiche prob haben finden eine lösung


----------



## rs-plc-aa (23 März 2007)

> deshalb wird der vorige transfer teilweise durch diesen überschrieben.


 
genau das hat mich ein bissl stutzig gemacht...

Soll aber heißen dass BEIDE Lösungen an sich korrekt sind und es im prinzip egal ist welche man nun nimmt ?


----------



## volker (23 März 2007)

ja, beides funktioniert


----------



## rs-plc-aa (23 März 2007)

So nun für die Nachwelt die Version für die ich mich nun entschieden habe:

@Volker: Da war noch ein Tippfehler drin bei dir in der Version von deiner Homepage - T LB1 0 sollte mit sicherheit T LB 1 heissen...

Mein Verwendungszweck ist der daß ich nun meinen "Alarm_FB" (beinhaltet die komplette Abwicklung der Alarm_S / Alarm_SQ geschichte) nun endlich auch multiinstanzfähig hinbekommen habe !

Der Pointer ist zuständig für die Übergabe der jeweiligen Begleitwerte an die SFC 17 / 18 Aufrufe. Er bildet sich aus dem Instanzdatenbaustein des FBs, der Länge und der Anfangsadresse (hier Beginn des STAT-Bereichs)

So baute ich nun im ersten Netzwerk folgendes ein, und kann - da die Struktur immer gleich ist die Nummer des Instanz-DBs von aussen reinschieben !

Für alle die es interressiert:


```
// Den Begleitwerten einmalig den passenden Instanzdatenbaustein zuweisen
// Hierzu einen ANY_Pointer verwenden:
// Pointer im Format für die Begleitwerte der Alarm_S und SQ SFCs bilden
      L     B#16#10                     // TYP (Teil1): 10h für s7
      T     LB     0
      L     B#16#2                      // TYP (Teil2): BYTE
      T     LB     1
      L     12                          // Anzahl (Bytes) ab Startadresse
      T     LW     2
      L     #DI_Number                  // Nummer des Datenbausteins (IN:INT)
      T     LW     4
      L     1200                        // Startadresse im DB (Beginn STAT-Bereich)
      SLD   3                           // Pointer erzeugen
      T     LD     6
      L     B#16#85                     // Speicherbereichstyp: 85h für IDB
      T     LB     6
// Der hiermit erzeugte Pointer liegt nun im TEMP-Bereich ab Adresse 0
// Dort eine Variable #Begleitwerte des Typs ANY anlegen und bei SD zuweisen.
```
 
edit: Speicherbereichstyp von 84 auf 85 geändert (da Instanz-DB) !


----------



## rs-plc-aa (24 April 2007)

*Irgendwas stimmt da doch noch nicht*

 ...
Jetzt muss ich die Geschichte doch noch mal aufgreifen - leider.

Also ich stehe jetzt kurz vor der Abnahme der Anlage und musste mich mit allerhand Kram rumärgern (Teile kamen nicht rechtzeitig / defekt - usw.) und hatte im zuge der IB manchmal schon ein wenig gestutzt daß bis jetzt noch kein Begleitwert funktionierte (immer 0). Heute hatte ich dann mal Zeit der Sache auf den Zahn zu fühlen.

Die beschriebene Methode muss irgendwo noch einen Fehler haben - ich habe nun mal zum Test an einer Störung die ich auf jeden Fall herbei bringe und die einen Begleitwert hat am SD-Eingang der SFC17 den AnyZeiger entfernt und direkt den ersten (in dem Fall einzigen) Begleitwert direkt angegeben -> das hat funktioniert

Das bedeutet also daß am Panel der richtige Text mit dem passenden Begl.Wert ankam.

Was also geht an dem AnyZeiger nicht ?

Der AnyZeiger wird am Beginn des FBs gebildet und verweist im Prinzip auf den aktuellen Instanzdatenbaustein des Alarm-FBs, genauer gesagt auf dessen Beginn des STAT-Bereichs. Hier sind 3 Begleitwerte deklariert die vor jedem Aufruf einer SFC 17/18 mit den passenden Werten gefüllt werden. Im Endeffekt wird das so benötigt da die SFC 17/18 nur alle Begleitwerte in einem Rutsch einlesen kann, also bei mehr als einem mit einem Pointer. Das hatte bisher bei nur einer einzigen Instanz funktioniert da der Pointer die Adresse des IDBs beinhaltete. Nun möchte ich aber den selben FB in mehreren Instanzen laufen lassen - daher benötige ich nun einen Umweg um die Adresse anzugeben. Der Ansatz war eigentlich auch schlüssig nur verstehe ich jetzt nicht so ganz was da nicht gehen soll.

ABER: Vielleicht geht das ja noch viel einfacher...

Ne Alternative hätte ich schon mal ausgedacht:

Warum den Umweg überhaupt über den STAT-Bereich machen ? Wäre es nicht schon ausreichend die Begleitwerte in den TEMP-Bereich zu verschieben und einen "normalen" Pointer darauf zu richten ?

Damit stets der korrekte Wert mitgegeben wird muß dieser ja sowieso immer neu zugewiesen werden.

Sprich: Die Begleitwerte müssen ja gar nicht gespeichert werden da sie beim nächsten SFC17/18 Aufruf im selben FB ohnehin immer erneuert werden müssen...

Bin mir jetzt auch ziemlich sicher daß das klappen würde, nur hätte ich trotzdem zu gern gewusst was da jetzt mit dem AnyZeiger nicht geht.


----------



## godi (24 April 2007)

Hallo!

Stelle sonst mal deinen Pointer so wie du ihn gemacht hast hier herein.

Ich mache es so: (Habe ich jetzt auf einen Instanz DB geändert)

```
//Für Flexible gestalteten Datenbaustein
      L     DINO                        //Wenn der Pointer in dem FB gebildet wird von dem du auf den Instanz Datenbaustein zugreifen willst (DINO = Nummer des Insatnzdatenbaustein)
      T     #DB_Nummer                  //Es kann aber auch ein X beliebige Datenbaustein Nummer (vorrausgesetzt es gibt den Datenbaustein) in DB_Nummer Transferiert werden
 
//ANY Pointer für Datentypen
      L     P##Temp_ANY_Pointer_in      //Lade Pointer von Variable
      LAR1                              //Schreibe Pointer in Adressregister 1
      L     B#16#10                     //Syntax ID für Step7
      T     LB [AR1,P#0.0]
      L     B#16#2                      //Wert für TYP: 1 Bool, 2 Byte, 3 Char, 4 Word, 5 Int, 6 Dword, 7 Dint, 8 Real, 9 Date, A TOD, B Time, C S5Time, E DT, 13 String
      T     LB [AR1,P#1.0]
      L     DILG                        //Anzahl der zu Übertragenden Daten zb. für 5 Byte einfach 5 (in diesem fall wird der ganze DB kopiert, Bei globalen DB den Befehl DBLG)
      T     LW [AR1,P#2.0]
      L     #DB_Nummer                  //Datenbausteinnummer
      T     LW [AR1,P#4.0]
      L     P#DBX 0.0                   //Bereichszeiger, in diesem Fall vom ersten Bit an. Wenn von Byte 10 an erwünscht dann  P#DBX 10.0 
      T     LD [AR1,P#6.0]
 
      CALL  SFC   20
       SRCBLK :=#Temp_ANY_Pointer_in
       RET_VAL:=MW0
       DSTBLK :=#Temp_ANY_Pointer_out
 
Alle Variablen sind im Temp bereich abgelegt
Temp_ANY_Pointer_in : ANY ; 
Temp_ANY_Pointer_out : ANY ; 
DB_Nummer : INT ;
```
 
Ich hoffe es hilft dir nochmals weiter.

godi


----------



## rs-plc-aa (25 April 2007)

Na ja ich hatte es so wie es oben gepostet ist - also:

```
// Den Begleitwerten einmalig den passenden Instanzdatenbaustein zuweisen
// Hierzu einen ANY_Pointer verwenden:
// Pointer im Format für die Begleitwerte der Alarm_S und SQ SFCs bilden
      L     B#16#10                     // TYP (Teil1): 10h für s7
      T     LB     0
      L     B#16#2                      // TYP (Teil2): BYTE
      T     LB     1
      L     12                          // Anzahl (Bytes) ab Startadresse
      T     LW     2
      L     #DI_Number                  // Nummer des Datenbausteins (IN:INT)
      T     LW     4
      L     1200                        // Startadresse im DB (Beginn STAT-Bereich)
      SLD   3                           // Pointer erzeugen
      T     LD     6
      L     B#16#85                     // Speicherbereichstyp: 85h für IDB
      T     LB     6
// Der hiermit erzeugte Pointer liegt nun im TEMP-Bereich ab Adresse 0
// Dort eine Variable #Begleitwerte des Typs ANY anlegen und bei SD zuweisen.
```
 
Ok die Übergabe von #DI_Number wäre überflüssig wenn man L DINO verwendet, klar.

Was bei deinem Beispiel für mich nicht klar ist - und das ist ja genau das Thema wo ich null Ahnung von habe - was mit dem Adressregister passiert?

Ganz einfach formuliert hätte es ein variabler Pointer werden sollen der unabhängig welche Nummer der aktuelle Instanz-DB hat -> immer auf den Beginn des STAT_Bereichs zeigt, weil dort die drei einzelnen Begleitwerte zwischengespeichert werden die nur als "12 Byte Stück" der SFC 17/18 mitgegeben werden können...

Daher meine Idee das aus dem STAT Bereich rauszuschmeißen und in den TEMP Bereich verschieben.

Dann würde der Pointer IMMER z.B. P#L0.0 Byte 12 heissen - an jedem SFC17/18 CALL. Der aktuelle Wert muss ja ohnehin passend zur Meldung UNMITTELBAR vorher reinkopiert werden.


----------



## godi (25 April 2007)

Habe dir das mit der indirekten Adressierung noch mal Kommentiert villeicht hilfts weiter. Ansonsten im Forum suchen und die Hilfe von S7 lesen. Da ist das ganze auch brauchbar beschrieben.


```
//Für Flexible gestalteten Datenbaustein
      L     DINO                        //Wenn der Pointer in dem FB gebildet wird von dem du auf den Instanz Datenbaustein zugreifen willst (DINO = Nummer des Insatnzdatenbaustein)
      T     #DB_Nummer                  //Es kann aber auch ein X beliebige Datenbaustein Nummer (vorrausgesetzt es gibt den Datenbaustein) in DB_Nummer Transferiert werden
//ANY Pointer für Datentypen
      L     P##Temp_ANY_Pointer_in      //Lade Pointer von Variable
      LAR1                              //Schreibe Pointer in Adressregister 1. Jetzt steht die Anfangsadresse der Variable im Adressregister 1 (wenn du in der Deklaration den Temp Bereich aufmachst hast du eine Spalte wo die Adresse steht. Dieser Wert steht jetzt im AR 1)
      L     B#16#10                     //Syntax ID für Step7
      T     LB [AR1,P#0.0]              //Transferiere Syntax ID für Step7 in das Byte 0 von Temp_ANY_Pointer_in (Warum Byte 0? Wegen dem P#0.0 => gibt Offset an)
      L     B#16#2                      //Wert für TYP: 1 Bool, 2 Byte, 3 Char, 4 Word, 5 Int, 6 Dword, 7 Dint, 8 Real, 9 Date, A TOD, B Time, C S5Time, E DT, 13 String
      T     LB [AR1,P#1.0]              //Hier wird in Byte 1 Transferiert weil AR1 + P#1.0 = Byte 1 von Temp_ANY_Pointer_in
      L     DILG                        //Anzahl der zu Übertragenden Daten zb. für 5 Byte einfach 5 (in diesem fall wird der ganze DB kopiert, Bei globalen DB den Befehl DBLG)
      T     LW [AR1,P#2.0]              //Hier wird das AR1 um P#2.0 erhöht. Also jetzt wird das Byte 2 angesprochen 
      L     #DB_Nummer                  //Datenbausteinnummer
      T     LW [AR1,P#4.0]
      L     P#DBX 0.0                   //Bereichszeiger, in diesem Fall vom ersten Bit an. Wenn von Byte 10 an erwünscht dann  P#DBX 10.0 
      T     LD [AR1,P#6.0]

      CALL  SFC   20
       SRCBLK :=#Temp_ANY_Pointer_in
       RET_VAL:=MW0
       DSTBLK :=#Temp_ANY_Pointer_out
 
Alle Variablen sind im Temp bereich abgelegt
Temp_ANY_Pointer_in : ANY ; 
Temp_ANY_Pointer_out : ANY ; 
DB_Nummer : INT ;
```


----------



## rs-plc-aa (25 April 2007)

Ok, ich komm schon in etwa mit...

Jetzt dämmerts glaube ich schon langsam.

Der von mir gepostete Code macht doch eigentlich das selbe nur wird dort direkt in den Lokaldatenbereich geschrieben.

Q1: Warum also überhaupt das Adressregister benutzen ? - Geht es NUR so ? (vielleicht geht es bei mir deshalb nicht?)

Q2: Muss dies vor JEDEM Ansprechen der Daten erneut ausgeführt werden ? - Ich habe das ja nur am Anfang des FBs stehen und es soll für alle Operationen die danach den Speicherbereich verwenden gültig sein -> geht es vielleicht deshalb nicht ?


----------



## volker (25 April 2007)

vom prinzip sollte dein zeiger funktionieren.
siehe mal ein bild

im unteren beispiel baust du den zeiger indirekt.
bei der anweisung lar1 siehst du, dass im ar1 die anfangsadresse 12.0 steht wie auch im deklarationsbereich.
die folgenden anweisungen mit dem ar1 beziehen sich nun auf diese anfangsadresse.
      T     LD [AR1,P#6.0]
dies transferiert also in das ld18

der vorteil ist offensichtlich. 
fügst du ein variable vor dem any-zeiger in den dekl.bereich ein verschieben sich seine adressen und bei direkter adressierung müsstest du dein programm anpassen. bei indirekten ist das egal, da du ja mit
L     P##varany
LAR1
die anfangsadresse des any-zeigers ins ar lädst.


----------



## rs-plc-aa (25 April 2007)

Soweit klar,
nur wenn ich das auf meinen Fall umlege dann sieht das so aus:

Du lädst "33" in den DB, baust den Zeiger und setzt Ihn an "SRCBLK"...

Ich baue den Zeiger, lade anschließend "33" und setze ihn an "SRCBLK"...

Dann fasse ich den Zeiger nicht mehr an und lade dann z.B. "44", transferiere das in den DB und gehe davon aus daß der Zeiger immer noch dort hinzeigt - setze also ohne ihn erneut zu bauen an "SRCBLK" und dachte daß dann "44" übertragen wird...

Ist hier der Fehler ?


----------



## volker (25 April 2007)

die richtung ist völlig egal.
der anyzeiger bleibt dir auf jeden fall erhalten. 
prüfe mal, ob du irgendwo im baustein in den lokaldatenbereich schreibst.


----------



## rs-plc-aa (25 April 2007)

mach ich...

Melde mich dann wieder.


----------



## rs-plc-aa (25 April 2007)

Hab noch mal nachgeschaut... Hier noch mal das komplette Netzwerk 1:

```
// Den Begleitwerten einmalig den passenden Instanzdatenbaustein zuweisen
// Hierzu einen ANY_Pointer verwenden:
// Pointer im Format für die Begleitwerte der Alarm_S und SQ SFCs bilden
      L     B#16#10                     // TYP (Teil1): 10h für s7
      T     LB     0
      L     B#16#2                      // TYP (Teil2): BYTE
      T     LB     1
      L     12                          // Anzahl (Bytes) ab Startadresse
      T     LW     2
      L     #DI_Number                  // Nummer des Datenbausteins (IN:INT)
      T     LW     4
      L     1170                        // Startadresse im DB (Beginn STAT-Bereich)
      SLD   3                           // Pointer erzeugen
      T     LD     6
      L     B#16#85                     // Speicherbereichstyp: 85h für Instanz-DB
      T     LB     6
// Der hiermit erzeugte Pointer liegt nun im TEMP-Bereich ab Adresse 0
// Dort eine Variable #Begleitwerte des Typs ANY anlegen und bei SD zuweisen.
// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Abbilder der DBs Alarm_S_Bits und Alarm_SQ_Bits temporär zwischenspeichern
      L     #DB_Nr_Alarm_S_Bits
      T     #DB_Nr_Alarm_S_Bits_Int
      AUF   DB [#DB_Nr_Alarm_S_Bits_Int]
      L     DBD    0
      T     #Abbild_AlmS_Bits_DBD0      // Inhalt des DBD 0 lokal gespeichert
      L     DBD    4
      T     #Abbild_AlmS_Bits_DBD4      // Inhalt des DBD 4 lokal gespeichert
      L     DBD    8
      T     #Abbild_AlmS_Bits_DBD8      // Inhalt des DBD 8 lokal gespeichert
      L     DBD   12
      T     #Abbild_AlmS_Bits_DBD12     // Inhalt des DBD 12 lokal gespeichert
      L     #DB_Nr_Alarm_SQ_Bits
      T     #DB_Nr_Alarm_SQ_Bits_Int
      AUF   DB [#DB_Nr_Alarm_SQ_Bits_Int]
      L     DBD    0
      T     #Abbild_AlmSQ_Bits_DBD0     // Inhalt des DBD 0 lokal gespeichert
      L     DBD    4
      T     #Abbild_AlmSQ_Bits_DBD4     // Inhalt des DBD 4 lokal gespeichert
      L     DBD    8
      T     #Abbild_AlmSQ_Bits_DBD8     // Inhalt des DBD 8 lokal gespeichert
      L     DBD   12
      T     #Abbild_AlmSQ_Bits_DBD12    // Inhalt des DBD 12 lokal gespeichert
// /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
// *********************************************************************************************************
//    eigentlicher Beginn Netzwerk 1 ...
// *********************************************************************************************************
      L     #T_MOT_OUT_C
      T     #begleitwert1
      L     L#0                         // falls ein Wert ausreicht die restlichen 2 mit "0" auffüllen
      T     #begleitwert2
      T     #begleitwert3
// Störung 1
      CALL  "ALARM_S"
       SIG    :=L16.0                   // Meldungsauslösendes Bit aus jeweiligem DB lokal gespeichert
       ID     :=W#16#EEEE               // Bleibt konstant gleich
       EV_ID  :=#Stoerung001            // Variable aus IN-Bereich welcher die Meldungsnummer zugeordnet ist
       SD     :=#Begleitwerte           // Pointer auf die Begleitwerte im STAT-Bereich (siehe oben)
       RET_VAL:=#retval                 // Rückgabewert für Fehlercodes
```
Die Netzwerke 2 - n beinhalten dann jeweils nur die nachfolgenden SFC 17/18 Aufrufe und die Zuweisung der Begleitwerte. Beispiel Netzwerk 2:

```
L     #T_OEL_C
      T     #begleitwert1
      L     L#0
      T     #begleitwert2
      T     #begleitwert3
// Störung 2
      CALL  "ALARM_S"
       SIG    :=L16.1
       ID     :=W#16#EEEE
       EV_ID  :=#Stoerung002
       SD     :=#Begleitwerte
       RET_VAL:=#retval
```
Das geht dann einfach so weiter...
Testen kann ich das erst wieder heute nachmittag, aber so wie es jetzt gepostet ist läufts aktuell und funktioniert NICHT -> Begleitwert ist immer = 0

An SD soll ja der Anyzeiger mitteilen wo die Begleitwerte liegen -> in dem Fall im STAT-Bereich des Instanzdatenbausteins, diese werden vor Aufruf der nächsten Störung immer neu versorgt (Begleitwert1, 2 und 3)

Ich weiss einfach nicht was da nicht gehen soll...

Ersetze ich an SD den Any #Begleitwerte durch #begleitwert1 (direkt aus STAT) dann funktioniert es, habe dann allerdings nur einen Wert statt 3 (manchmal brauche ich 2, den dritten habe ich als reserve schon mal vorgesehen...)
Also muss es irgendwie an dem Zeiger hängen...


----------



## godi (25 April 2007)

Hallo!

#Begleitwert ist dein Any Zeiger? 
Liegt der im Temp bereich bei Adresse 0.0?

Wo wird die Variable #DI_Nummer beschrieben?

Gibt Ret_Val von deinen SFC aufrufen einen Wert zurück?

godi


----------



## Onkel Dagobert (25 April 2007)

Hallo rs-plc-aa,

ich habe den Beitrag jetzt nur kurz überflogen. Deine Begleitwerte liegen in den Lokaldaten? Wie sieht die Deklaration aus? Ich denke, du musst garkeinen Pointer basteln. Deklariere deine Begleitwerte als STRUCT oder als ARRAY und schreibe diesen direkt an die SFC. Alles andere erledigt Step7 für dich.

Gruß, Onkel


----------



## rs-plc-aa (25 April 2007)

godi schrieb:


> Hallo!
> 
> #Begleitwert ist dein Any Zeiger?
> Liegt der im Temp bereich bei Adresse 0.0?


ja, steht ganz oben wo der Any Zeiger gebaut wird darunter als Kommentar...


			
				godi schrieb:
			
		

> Wo wird die Variable #DI_Nummer beschrieben?


Ist ein IN Parameter (INT) und wird am OB als Zahl drangeschrieben -> kann sicherlich durch DINO ersetzt werden...


			
				godi schrieb:
			
		

> Gibt Ret_Val von deinen SFC aufrufen einen Wert zurück?
> 
> godi


nix fehlerhaftes zumindest



			
				Onkel Dagobert schrieb:
			
		

> Deine Begleitwerte liegen in den Lokaldaten? Wie sieht die Deklaration aus? Ich denke, du musst garkeinen Pointer basteln. Deklariere deine Begleitwerte als STRUCT oder als ARRAY und schreibe diesen direkt an die SFC. Alles andere erledigt Step7 für dich.


Die Begleitwerte liegen im STAT -> darauf soll der Zeiger zeigen...

Wenn das jetzt nicht geht werde ich sie aber in TEMP verschieben und einen normalen Pointer über die Länge aller 3 darauf setzen - das funktioniert. Wie das als Array geht weiss ich nicht, würde aber ziemlich sicher auch ohne gehen.

Mir geht´s jetzt hauptsächlich noch darum zu wissen warum das jetzt nicht geht weil ich es vielleicht für was anderes noch brauchen kann.


----------



## godi (25 April 2007)

rs-plc-aa schrieb:


> ja, steht ganz oben wo der Any Zeiger gebaut wird darunter als Kommentar...


 
Habe damit gemeint ob die Variable Begleitwert (als Any) in der Deklaration im Temp bereich angelegt ist und ganz oben steht. Also mit Adresse 0.0 beginnt?


----------



## volker (25 April 2007)

vom prinzip kann ich keinen fehler entdecken.
mach mal nen scrennshot wenn der online bearbeitet wird (so ich ich das angehängt hatte.)
eins von der bildung des any und eins vom aufruf der sfc17

vor dem sfc aufruf füge vorher ein
L LD 0
L LW 4
L LD 6
nur um zu sehen ob da noch der zeiger stimmt.


----------



## rs-plc-aa (25 April 2007)

godi schrieb:


> Habe damit gemeint ob die Variable Begleitwert in der Deklaration im Temp bereich angelegt ist und ganz oben steht. Also mit Adresse 0.0 beginnt?


Ja -> Name: Begleitwerte ; Typ: Any ; Adresse: 0.0

Die 3 eigentlichen Werte sind im STAT die einzigen Variablen. Der Zeiger soll also auf den Instanzdatenbaustein verweisen, und zwar auf Adresse 1170.0 und das ganze 12 Byte lang...

Das mit dem Screenshot werde ich Nachreichen (geht jetzt im Moment nicht)


----------



## godi (25 April 2007)

komisch...  
Sollte eigentlich funktionieren


----------



## rs-plc-aa (25 April 2007)

Ich mach heute wahrscheinlich keinen Abstecher mehr dort hin aber wahrscheinlich morgen.

Dann schaue ich das alles im Status noch mal ganz genau an und füge mal noch Screenshots dazu.

Jetzt weiß ich wenigstens daß nichts gravierendes sein kann.

Danke schon mal...


----------



## Onkel Dagobert (25 April 2007)

rs-plc-aa schrieb:


> ..Jetzt weiß ich wenigstens daß nichts gravierendes sein kann..


Da wäre ich mir nicht so sicher. Am meisten stört mich dass du in einem FB eine Nr. für einen Instanz-DB als Eingang anlegst und diesen dann in einem ANY weitergibst. Wahrscheinlich zeigt danach dein DI-Register nicht mehr auf den Instanz-DB des FB, sondern auf den, der als Eingangsparameter angegeben ist. Wenn du mit der DB-Nr. flexibel sein willst, musst du schon einen Global-DB verwenden. Widersprüchlich ist dies ohnehin, da ja die Daten, auf die zugegriffen werden sollen, in den temporären oder statischen Lokaldaten des FB stehen.

Mach dir's nicht so schwer. Folgende Abbildung zeigt zwei Variablendeklarationen, mit denen du symbolisch einen ANY-Pointer übergeben kannst. Step7 generiert den passenden Pointer für dich, egal ob er auf die temorären oder statischen Lokaldaten zeigt. Probiert habe ich es nicht, aber generell sollte es so gehen.

Vergib mir, falls ich falsch liege. Zum Testen habe ich momentan keine Zeit.



rs-plc-aa schrieb:


> ..Dann schaue ich das alles im Status noch mal ganz genau an und füge mal noch Screenshots dazu..


Achte dabei besonders auf die DB-Register! Unter Extras-Einstellung-AWL kannst du die Anzeige aktivieren.


Gruß, Onkel


----------



## rs-plc-aa (25 April 2007)

Das DB Register scheint ja zu passen (falls es sich um die Spalte DB2 und nicht DB1 handelt -> habe jetzt mal PLCSIM angeworfen...)

Die DB Nummer von aussen ist nicht sehr glücklich gewählt, zumal es sich um seine (FB) eingene DI Nummer handelt - also L DINO würde reichen - kommt aber zunächst aufs selbe raus...

@Onkel Dagobert: Dein Vorschlag - vor allem der mit dem Struct gefällt mir sehr gut da ich eigentlich immer für´s einfachst-mögliche bin.
Die Variante mit dem Array -> Wie beschreibe ich dort die Einzelwerte ?
\@Onkel Dagobert

Aber mir lässt das trotzdem keine Ruhe - es geht wahrscheinlich mittlerweile bloß noch ums Prinzip (-> den "Fehler" zu finden...).


----------



## Onkel Dagobert (25 April 2007)

rs-plc-aa schrieb:


> ..Die Variante mit dem Array -> Wie beschreibe ich dort die Einzelwerte ?..


 
Einfach den Index in eckigen Klammern angeben.

L 123
T BEGLEITWERTE_1[1]


Gruß, Onkel


----------



## rs-plc-aa (25 April 2007)

Danke dir, das kann ich sicher auch mal brauchen...

Ich habe jetzt die Variante mit der Struct vollständig umgesetzt (gefiel mir hierfür einfach besser)

Der weitere Vorteil hierbei -> Wenn Begleitwerte ergänzt werden sollen (es ist ja noch Reserve an Meldungen) dann brauche ich ja einen Wert von aussen. D.h. es muß die IN-Schnittstelle erweitert werden, wodurch sich wiederum die Anfangsadresse des Stat-Bereichs verschieben würde.

Hier müßte der Zeiger wieder angepasst werden damit er auch wieder korrekt "zeigt".

Mit der Struct / Array Version fällt das flach da hier ja die tatsächliche Adresse uninteressant ist...

Wie hieß gleich der Slogan? -> warum einfach wenn´s auch kompliziert geht...

Der Test an der echten Steuerung steht zwar noch aus (also vielleicht doch nicht gleich die Klappe so weit aufreissen  ) aber das scheint syntaktisch alles zu passen und sollte daher auch funieren...

Zum Any-Zeiger: Ein wenig wurmt´s mich jetzt schon daß es nicht geklappt hat aber das muß ja nicht heissen daß es an anderer stelle nicht noch mal aufgeriffen wird - von daher trotzdem danke an alle für die Mithilfe, geschadet hat´s ja auf jeden Fall nicht.

P.S.: Wenn der Test morgen fehlschlägt melde ich mich ja sowieso wieder  , aber wenn es klappt ist sicher auch niemand böse daß ich den Lösungsweg nun verworfen habe (es muß halt auch vorwärts gehen...)


----------



## rs-plc-aa (26 April 2007)

rs-plc-aa schrieb:


> (also vielleicht doch nicht gleich die Klappe so weit aufreissen  )


 
Hat "geklappt"  

Danke noch mal...


----------

