ANY-Pointer auf temporären Struct im FB

ChristianPaier

Level-1
Beiträge
44
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute...

Ich bin gerade dabei mich ein wenig in die any Pointer einzuarbeiten...

Folgenden Gegebenheiten: Ich bin berade dabei ein Motorbaustein für diverse Antriebe zu schreiben. In einem seperaten DB befinden sich die Daten (jeweils 50Byte) für die Antriebe.

Ich möchte nun am Anfang des Motor-FBs die Daten aus dem DB in einen struct (gleich aufgebaut wie Motordaten im DB) im temporären Bereich des Fb's laden. Der FB arbeitet dann seine übrigen Funktionen ab und schreibt es am Ende wieder zurück.

Ich hab mir dabei gedacht das man dem Baustein die DBNr und den Anfang und die Länge übergibt. Mit den Daten kann ich dan einen Quellzeiger aufbreiten.
Mit dem Tutorial http://sps-forum.de/showthread.php?t=12923 hab ich den Quellzeiger für den BLKMOV schon hinbekommen.

#IN : Quelle_DBNR (INT) 0.0
Quelle_Anfang (INT) 2.0
Quelle_Laenge (INT) 4.0

#Temp: Zeiger_Quelle (any) 0.0
Zeiger_Ziel (any) 10.0
Motordaten (struct) 20.0

//Quellzeiger
L P##Zeiger_Quelle
LAR1
L W#16#1002
T LW [AR1,P#0.0]
L #Quelle_DBNR
T LW [AR1,P#4.0]
L #Quelle_Anfang
SLD 3
OD DW#16#84000000
T LD [AR1,P#6.0]
L #Quelle_Laenge
T LW [AR1,P#2.0]

Jetzt happert es nur am Zielzeiger für den temporären Struct. Wie muss der ausschauen?

Mit Bitte um Hilfe
Christian
 
das müßte dann ungefähr so aussehen :
Code:
//Quellzeiger
L P##Zeiger_Ziel
LAR1 
L W#16#1002
T LW [AR1,P#0.0]
L 0
T LW [AR1,P#4.0]
L p##Motordaten
OD DW#16#86000000
T LD [AR1,P#6.0]
L #Quelle_Laenge
T LW [AR1,P#2.0]
.. ist nicht getestet ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Aha wie ich sehe war ich schon nahe dran... (siehe übersprungenen Codeteil)

@ Larry ich hab deinen Codeteil mal in Folgenendem Beispielprojekt implementiert.

Motor-DB: DB10 3Byte lang

Aufruf des Motor-FBs in OB1 mit den Werten:
Quelle_DBNR: 10
Quelle_Anfang: 0
Quelle_Länge: 3

Motorbaustein:
Code:
//Quellzeiger aufbreiten
      L     P##Zeiger_Quelle
      LAR1  
      L     W#16#1002
      T     LW [AR1,P#0.0]
      L     #Quelle_DBNR
      T     LW [AR1,P#4.0]
      L     #Quelle_Anfang
      SLD   3
      OD    DW#16#84000000
      T     LD [AR1,P#6.0]
      L     #Quelle_Laenge
      T     LW [AR1,P#2.0]

//Zielzeiger aufbreiten (Eigen)
      SPA   M001

      L     P##Zeiger_Ziel
      LAR1  
      L     W#16#10
      T     LB [AR1,P#0.0]
      L     W#16#2
      T     LB [AR1,P#1.0]
      L     #Quelle_Laenge
      T     LW [AR1,P#2.0]
      L     0
      T     LW [AR1,P#4.0]
      L     20
      SLD   3
      T     LD [AR1,P#6.0]
      L     B#16#86
      T     LB [AR1,P#6.0]
M001: NOP   0

//Zielzeiger aufbreiten (Larry)
      L     P##Zeiger_Ziel
      LAR1  
      L     W#16#1002
      T     LW [AR1,P#0.0]
      L     0
      T     LW [AR1,P#4.0]
      L     P##Motor
      OD    DW#16#86000000
      T     LD [AR1,P#6.0]
      L     #Quelle_Laenge
      T     LW [AR1,P#2.0]

//Daten laden
      CALL  "BLKMOV"
       SRCBLK :=#Zeiger_Quelle
       RET_VAL:=#Fehlercode
       DSTBLK :=#Zeiger_Ziel

//Interne DB-Funktionen
      L     #Motor.Byte1
      L     #Motor.Byte2
      +I    
      T     #Motor.Byte3

//Daten rausschreiben
      CALL  "BLKMOV"
       SRCBLK :=#Zeiger_Ziel
       RET_VAL:=#Fehlercode
       DSTBLK :=#Zeiger_Quelle


Leider hatte ich damit noch keine Erfolg. Die BLKMOV liefern beide Fehlercodes (33573 und 33060) und wenn ich die Bytes im Fb beobachte bleiben sie auch leer. Leider
 
wieso baust du dir einen zielzeiger?
zeiger_ziel ist doch schon ein any-pointer im tempbereich. lass deine aufbereitung mal weg
 
@ volker: wie meinst du das?

Sicher ist Zeiger Ziel bereits ein Any-Pointer. Aber er zeigt ja noch nicht auf den struct im temporären Bereich des FB oder???

irgendwie muss der BLKMOV ja wissen wo er die Daten hischreiben soll.

Das heißt ich muss irgendwie einen Any-Pointer erzeugen der auf diese Stelle im temporären Bereich zeigt.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bin jetzt schon mal soweit das es im beispiel mit 3Bytes funktioniert...
Das Problem ist nur ich weiß nicht wieso!

Code:
//Quellzeiger aufbreiten
      L     P##Zeiger_Quelle
      LAR1  
      L     W#16#1002
      T     LW [AR1,P#0.0]
      L     #Quelle_DBNR
      T     LW [AR1,P#4.0]
      L     #Quelle_Anfang
      SLD   3
      OD    DW#16#84000000
      T     LD [AR1,P#6.0]
      L     #Quelle_Laenge
      T     LW [AR1,P#2.0]

//Zielzeiger aufbreiten
      L     P##Zeiger_Ziel
      LAR1  
      L     W#16#1002
      T     LW [AR1,P#0.0]
      L     0
      T     LW [AR1,P#4.0]
      L     20
      SLD   3
      OD    DW#16#87000000 <<-- ACHTUNG SIEHE HIER
      T     LD [AR1,P#6.0]
      L     3
      T     LW [AR1,P#2.0]

//Daten laden
      CALL  "BLKMOV"
       SRCBLK :=#Zeiger_Quelle
       RET_VAL:=#Fehlercode
       DSTBLK :=#Zeiger_Ziel

//Daten ändern
      L     #Motor.Byte1
      L     #Motor.Byte2
      +I    
      T     #Motor.Byte3

//Daten zurückschreiben

      CALL  "BLKMOV"
       SRCBLK :=#Zeiger_Ziel
       RET_VAL:=#Fehlercode
       DSTBLK :=#Zeiger_Quelle

Ich hab als Speicherbereich des Zielzeigers 87 statt 86 verwendet. Jetzt funktioniert es. Aber warum? Schließlich ist 87 der Speicherbereich "Vorherige Lokaldaten" und 86 steht für "Lokaldaten (L-Stack)".

Was ist der unterschied zwischen beiden. Warum funktioniert das so???? :confused: :confused: :confused: :confused:
 
Hallo Christian,

Ich hab als Speicherbereich des Zielzeigers 87 statt 86 verwendet. Jetzt funktioniert es. Aber warum? Schließlich ist 87 der Speicherbereich "Vorherige Lokaldaten" und 86 steht für "Lokaldaten (L-Stack)".

Was ist der unterschied zwischen beiden. Warum funktioniert das so???? :confused: :confused: :confused: :confused:

der SFB 20 greift mit 87 auf die Lokaldaten deines Motor-FBs zu. Mit 86 würde er auf seine eigenen Lokaldaten zugreifen.

Grüße
Gebs
 
Aha, verstehe schon. :)

Das heist das es eigentlich vorher hauptsächlich (ich sag bewusst hauptsächlich) am falschen Speicherbereich gelegen hat. Oder?
 
@ volker: wie meinst du das?

Sicher ist Zeiger Ziel bereits ein Any-Pointer. Aber er zeigt ja noch nicht auf den struct im temporären Bereich des FB oder???

irgendwie muss der BLKMOV ja wissen wo er die Daten hischreiben soll.

Das heißt ich muss irgendwie einen Any-Pointer erzeugen der auf diese Stelle im temporären Bereich zeigt.

da du die ganze zeit vom temporären bereich geschrieben hast, bin ich davon ausgegangen das du im deklarationsbereich temp meinst.
so wie es jetzt aussieht, meintest du aber den stat - bereich.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Volker:
das war schon so korrekt - ich hatte da nicht richtig aufgepasst. Für den SFC20 sind die Lokaldaten (TEMP) des aufrufenden Bausteins natürlich die vorherigen Lokaldaten (Kennung 87 und nicht 86) - siehe Beitrag von Gebs ...

@Christian:
du kannst deshalb trotzdem den Codevorschlag von mir übernehmen (nur eben mit der richtigen Kennung : 87 !!!). Der Vorteil des symbolischen Pointers (L p##Motordaten) gegenüber der absoluten Adressierung bei dir (L 20 und dann SLD 3) ist der, dass sich hier der Pointer automatiosch anpasst, wenn du deinen TEMP-Bereich mal veränderst.

und noch etwas :
der Zielbereich vom Blockmove muß natürlich genauso groß (oder größer) sein, wie die Menge der Daten, die du kopieren willst. Der eine der beiden Fehler, die du hattest besagte nämlich, dass dein Zielbereich nicht ausreichend groß genug war ...

Gruß
LL
 
@Christian:
Der Vorteil des symbolischen Pointers (L p##Motordaten) gegenüber der absoluten Adressierung bei dir (L 20 und dann SLD 3) ist der, dass sich hier der Pointer automatiosch anpasst, wenn du deinen TEMP-Bereich mal veränderst.

So war es ja auch von Anfang an gedacht. Aber da ich mich seit heute morgen erst mit Pointern befasse war mir das noch ein wenig zu heiss. Da es mit der absoluten Adressierung aber jetzt schon funktioniert mache ich mich jezt mal dran es indirekt aufzubauen.

Noch was... Ich möchte für den Quellzeiger dem Baustein direkt einen Pointer übergeben, aber ich bin mir nicht sicher ob das geht oder ob es an der schreibweise liegt.
p#db10.dbb0 (geht so mal nicht)
 
Zuletzt bearbeitet:
leider kann man an die sfc20 keinen anyzeiger aus dem in-bereich legen
du kannst das aber umtransferieren in den temp-bereich.
z.b. so
obs eleganter geht weiss ich im mom nicht
Code:
      L     P##any_in  //in-parameter vom typ any
      LAR2  
      L     B [AR2,P#1.0]               // TYP in AKKU1-L laden (2=bytes)
      L     W [AR2,P#2.0]               // Anzahl Elemente        
      T     #laenge                // Laenge Bereich in Bytes
 
 
l _p##any_temp
lar1
l d [ar2,p#0.0]
t d [ar1,p#0.0]
l d [ar2,p#4.0]
t d [ar1,p#4.0]
l w [ar2,p#8.0]
t w [ar1,p#8.0]

Code:
      L     P##date_time  //in-parameter vom typ date_and_time
      LAR1  
      L     W [AR1,P#0.0]               //DB-Nr. der Eingangsvariablen oder Null
      T     #DB_NR
      AUF   DB [#DB_NR]                 //Aufschlagen über das DB-Register
      L     D [AR1,P#2.0]               //Bereichszeiger auf die Variable
      LAR1                              //AR1 plus DB-Register zeigen auf Variable
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Also ich finde ja obige Ausführungen zu den Any-Pointern durchaus interessant,
aber wäre für diesen Anwendungsfall ein IN/OUT Parameter als UDT nicht bedeutend einfacher?

Abgesehen davon auch noch bedeutend übersichtlicher ...

Mfg
Manuel
 
mal ne frage nebenbei
wie sieht die syntax am fc/fb aus wenn ich einen udt übergeben möchte?
 
@Volker:
so wie ich die Frage von dir verstanden habe : Die Beschaltung am FC / FB ist in etwa identisch, als wenn du einen String (z.B.) übergeben würdest. Hattest du das gemeint ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
aber wäre für diesen Anwendungsfall ein IN/OUT Parameter als UDT nicht bedeutend einfacher?

Abgesehen davon auch noch bedeutend übersichtlicher ...

Kann ich mir nicht vorstellen, die Motordaten liegen ja alle in einem zentralen Db der aus ca. 50 einzelnen Motor-udt's besteht. Die Visualisierung der Anlage wird von einen Fremdfirma mit diesem DB gemacht.

Da heisst mein Multi-Instanz Motor-FB muss auch in der Lage sein sich irgendwo aus diesem Datenbaustein die richtigen Daten für den jeweiligen Motor raus zu suchen, diese zu editieren und wieder zurück zu schreiben.

Ich weiß nicht ganz wie du das mit deinem Vorschlag meinst.
 
ok hat sich erledigt
irgendwie wollte er z.b. db2.udt_1 nicht schlucken.
nachdem ich mal den editor geschlossen habe und neu geöffnet gings :confused:
 
Kann ich mir nicht vorstellen, die Motordaten liegen ja alle in einem zentralen Db der aus ca. 50 einzelnen Motor-udt's besteht. Die Visualisierung der Anlage wird von einen Fremdfirma mit diesem DB gemacht.

Da heisst mein Multi-Instanz Motor-FB muss auch in der Lage sein sich irgendwo aus diesem Datenbaustein die richtigen Daten für den jeweiligen Motor raus zu suchen, diese zu editieren und wieder zurück zu schreiben.

Ich weiß nicht ganz wie du das mit deinem Vorschlag meinst.

Also ich sach mal so:
Du hast einen Motor-FB, diesen rufst du als Multiinstanz in einen weiteren FB 50 mal auf

Also so:
Call Motor_1
IN OUT dese Motors1

Call Motor_2
IN OUT dese Motors2

...

Als IN/OUT Parameter deines Motor-FB's hast du nun einen weiteren Parameter IN/OUT z.B. Visu vom TYP MotorUDT

Innerhalt deines Motor-FB schreibst du dann:
U BA_Hand
= Visu.BA_Hand

oder
L Motorstrom
T Visu.Motorstrom_Aktuell

L Visu.Sollwert
T Sollwert

Ich hoffe das Prinzip wäre klar ...

Obiges ist natürlich nur ein Beispiel, keine Ahnung was letzten Endes in deinem Motor-UDT steht ...

Mfg
Manuel
 
Zurück
Oben