Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 24

Thema: Auslesen Array aus DB über zwei Funktionen (ANY-Zeiger und Blkmov)

  1. #1
    Registriert seit
    28.11.2014
    Beiträge
    11
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Guten Tag liebe Member,

    ich bin schon länger stiller Mitleser und konnte mir hier immer gute Lösungsansätze holen, nun komme ich nicht weiter und benötige Hilfe.
    Zu meinem Vorhabenn:

    In einem FB x rufe ich FB y auf dieser besitzt auch einen DB y.
    Im FB y habe ich eine IN-Variable als Daten mit dem Datentyp ANY deklariert.
    Im FB x (FUP) gebe ich an der Variable Daten ein Array aus einem anderen DB an, Form: DB z.dbx 202.0 BYTE 12
    Dieser Eingang wird dann von Step 7 zu: "DB_z".S[2].A1.Read.DATEN.Datenteile.teilenummer umgeformt. Soweit ist alles gut.

    Jetzt will ich aber die Daten mit der Länge von 12 Bytes im FB y über ein Blockmove in den DB y schreiben/kopieren.

    Im FB y habe ich schon die Eingangswerte von E 0.0 bis E100.0 über ein ANY-Zeiger in den DB y geschrieben und genauso wieder raus. Sinn und Zweck der Verwendung des Anyzeiger war, das die Bausteine immer wieder verwendet werden können und sich selbst über die Variablen die Adresse holen. Das funktioniert auch, nur bei meinem vorhaben mit dem Array nicht.

    Mein Programm sieht folgender Maßen aus:
    Code:
    // Erstellung des Quell-Pointers
    
          LAR1     P##Quelle             //Lade die Anfangsadresse des ANY-Pointers in AR1
          L     B#16#10                     //S7-code immer b#16#10 = 10hex
          T     LB [AR1,P#0.0]
          L     B#16#2                      //Datentyp: 02 = Byte
          T     LB [AR1,P#1.0]
          L     12                      //Anzahl/Wiederholfaktor
          T     LW [AR1,P#2.0]
          L     0                           
          T     LW [AR1,P#4.0]
          L     B#16#0                      //Auswahl Eingänge bzw Speicherbereich
          T     LB [AR1,P#6.0]
          L     B#16#0                      //Adressbelegung: 0 = 000
          T     LB [AR1,P#7.0]              //Adressformat: Byte.Bit wobei Byte aufgeteilt in Bit0-2 von 7. Byte
          L     P##Datenholen            //Adressanfang (Zeiger)   
          SLD   3
          L     #Offset_Quelle              //Laden des Offsets
          +D                                // Addieren
    
          T     LW [AR1,P#8.0]              //Adressformat: Byte.Bit wobei Byte in Bit0-7 von 8.Byte
    
    
     CALL  "BLKMOV"
           SRCBLK :=#Quelle
           RET_VAL:=#RET_VAL_Block
           DSTBLK :=#Ziel
          NOP   0
    Der Fehler an Ret_Val lautet 8124 entspricht "Bereichsfehler beim lesen eines Parameters"
    Jedoch kann ich mit dem Fehler nicht viel anfangen, ich vermute es liegt an der Angabe im Speicherbereich des ANY-Zeigers.
    Nur was gebe ich an wenn meine Adresse eine ANY Variable (Datenholen) ist?


    Ich hoffe mir kann hier einer auf die Sprünge helfen und danke im Voraus!
    Geändert von UsernameS7 (28.11.2014 um 11:05 Uhr)
    Zitieren Zitieren Auslesen Array aus DB über zwei Funktionen (ANY-Zeiger und Blkmov)  

  2. #2
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.794
    Danke
    398
    Erhielt 2.417 Danke für 2.013 Beiträge

    Standard

    Hallo,
    also erstmal vorab - ich mußte das Ganze 3mal lesen um es so zu verstehen, wie ich es nun verstanden habe.
    Außerdem - ich kann meinen Vorschlag gerade nicht gegen-checken ... (ich schieße also aus der Hüfte - quasi aus der Erinnerung)
    Ich nehme folgendes an :
    Der IN-(oder INOUT-) Parameter deines FB_y vom Typ ANY ist, wenn du die die Instanz ansiehst, als Pointer ausgeführt (also in der Instanz nicht 10 Bytes sondern nur 6).
    Wenn dem so ist, dann mußt du dir den Pointer laden und an der Stelle stehen dann die Inhaltsdaten des ANY's mit dem du eigentlich arbeiten willst.
    Das heißt (noch einmal anders geschrieben) : die ANY-Daten für deinen Blockmove stehen an der Adresse, auf die dein IN-Parameter zeigt.
    Check das bitte mal ...

    Gruß
    Larry

  3. #3
    Registriert seit
    08.04.2008
    Ort
    Köln
    Beiträge
    844
    Danke
    39
    Erhielt 244 Danke für 199 Beiträge

    Standard

    Hallo UsernameS7!

    Mit
    Code:
     L     P##Datenholen            //Adressanfang (Zeiger)
    lädst Du die Anfangsadresse Deiner Variable #Datenholen in den Akku und nicht den Inhalt Deines Pointers.
    Wenn Du den Any einfach "durchreichen" willst, dann schau Dir das Beispiel vom Harald (PN/DP) an:
    http://www.sps-forum.de/simatic/6360...tml#post481732

    Damit sollte es funktionieren.

    Grüße
    Gebs

  4. #4
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.316
    Danke
    932
    Erhielt 3.331 Danke für 2.689 Beiträge

    Standard

    Also ich muß auch mehrmals lesen... und verstehe womöglich trotzdem nicht richtig, was Du da tun willst. Dein Programmcode passt auch irgendwie nicht zu dem was ich aus Deinen Ausführungen interpretiere...

    Zitat Zitat von UsernameS7 Beitrag anzeigen
    Der Fehler an Ret_Val lautet 8124 entspricht "Bereichsfehler beim lesen eines Parameters"
    In Deinem Programmcode bastelst Du einen ungültigen ANY-Pointer, indem Du 0 in die Speicherbereichskennung (Byte 6 von #Quelle) schreibst. Auf welchen Speicherbereich soll Dein ANY #Quelle zeigen?

    #Quelle ist eine ANY-Variable in TEMP?
    Wo taucht nun Dein ANY aus dem IN-Parameter "Daten" auf? (der, wo P#DB?.DBX202 BYTE 12 drinstehen soll)
    Und was sind #Datenholen und #Offset_Quelle für Variablen? Was steht da drin?


    Zitat Zitat von UsernameS7 Beitrag anzeigen
    Im FB y habe ich schon die Eingangswerte von E 0.0 bis E100.0 über ein ANY-Zeiger in den DB y geschrieben und genauso wieder raus. Sinn und Zweck der Verwendung des Anyzeiger war, das die Bausteine immer wieder verwendet werden können und sich selbst über die Variablen die Adresse holen. Das funktioniert auch, nur bei meinem vorhaben mit dem Array nicht.
    Hat das was mit Deinem Problem zu tun? Ich komm' nicht drauf... genausowenig, was die Verwendung von ANY-Pointern mit Wiederverwendbarkeit zu tun hat.


    PS: ANY werden an FB direkt als ANY (10 Byte) übergeben. (also nicht als 6-Byte-Pointer auf einen ANY)

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  5. #5
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.794
    Danke
    398
    Erhielt 2.417 Danke für 2.013 Beiträge

    Standard

    @Harald:
    OK ... dann war es bei den IN_OUT ein Pointer. Ich hatte das nicht mehr ganz sicher auf dem Schirm (hatte ich aber ja auch geschrieben).

    Gruß
    Larry

  6. #6
    UsernameS7 ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    28.11.2014
    Beiträge
    11
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Guten Morgen,

    vielen Dank schonmal für die Antworten.

    @ Larry: Der IN-Parameter Datenholen ist als ANY ausgeführt und hat eine Länge von 10 Bytes in der Instanz.

    @ Gebs: Mein Gedanke war auch durch die Anfangsadresse von Datenholen und durch die Längenangabe beim gebastelten ANY-Zeiger dem Blkmov zu übergeben. Also quasi die Daten die über den ANY Datenholen über die Bausteinschnittstelle kopieren und in meine Instanz kopieren. Die Daten bzw den Inhalt durchreichen würde dem ja gleich kommen, die Daten müssen in InstanzDB gespeichert sein.

    @ PN/DP: Genau das war mein Problem. Über den Speicherbereich also Byte 6 des ANY-Zeiger gebe ich ja an was es ist durch den Hexcode, also ob es E, A, DB, IDB oder Lokaledaten sind. Nur wusste ich nicht was ich hierangeben soll, da Datenholen ja an sich kein Eingang E ist.
    Ja, #Quelle ist eine ANY-Variable in Temp.
    #Offset-Quelle ist eine INT-Variable in Temp und gibt den Offset der Adresse wo die Daten beginnen an, hier ist dieser Null. Da die Anfangsadresse und die Länge der Daten ja schon über "DB z.dbx 202.0 BYTE 12" am IN-Parameter angegeben sind.
    Ich will die Daten die über die Bausteinschnittstelle "Datenholen" anliegen, über ein Blockmove in mein DB kopieren.

    Naja den ANY-Zeiger kann man für Wiederverwendbarkeit schon verwenden. Dadurch das ich ja den ANY-Zeiger verwende und die Adresse als Variable angebe, "sucht" der ja quasi im DB danach und über die Längenangabe weiß er wieviele Daten es sind. Hat den Vorteil das ich den Baustein ja auf andere SPSen kopieren kann, den DB erzeuge und alles funktioniert genauso ohne das ich im Programm Änderungen vornehme, sondern nur noch über die Bausteinschnittstellen etwas angebe. Das hat ja auch funktioniert, wie schon in dem Kommentar erwähnt, nur da kopiere ich mit Blkmov die Daten von meinen Eingängen in den DB und genauso davon auf die Ausgänge in dem Fall ja nicht.


    Ich werd mir das Beispiel morgen genauer anschauen, habe gerade leider wenig Zeit. Wollte mich aber trotzdem melden und schonmal Danke sagen.

  7. #7
    UsernameS7 ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    28.11.2014
    Beiträge
    11
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hallo,

    wenn ich das Beispiel richtig verstehe, dann müsste ich mein Code wie folgt umändern:

    Code:
          L     P##Datenholen            //relative Adresse #Datenholen in dieser Instanz (DI)
          TAR2                              //Transferiere Adressregister 2 in Akku 1
          UD    DW#16#FFFFFF                //Bereichskennung (DB) ausblenden
          +D                                //Addiere
          LAR1                              //Lade AR1 mit Inhalt von Akku 1: absolute Adresse #Datenholen im IDB (DI)
    
          LAR2  P##Quelle                   //Lade AR2: Adresse des TEMP-ANY
          L     DID [AR1,P#0.0]             //S7-code immer b#16#10 = 10hex + Datentyp + Wiederholfaktor
          T     LD [AR2,P#0.0]              //Transferiere nach Lokaldaten-Doppelwort Byte 0 von AR2
          L     DIW [AR1,P#4.0]             //Lade DB-Nummer
          T     LW [AR2,P#4.0]              //Transferiere nach Lokaldaten-Wort Byte 4 von AR2
          L     DID [AR1,P#6.0]             //Lade Bereichsadresse
          T     LD [AR2,P#6.0]              //Transferiere nach Lokaldaten-Doppelwort Byte 6 von AR2
    Wäre das so korrekt? Entschuldigt, bin aber leider noch nicht so firm mit ANY-Zeiger.

  8. #8
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.316
    Danke
    932
    Erhielt 3.331 Danke für 2.689 Beiträge

    Standard

    Ja, so geht das.
    Davor MUSS aber noch der Inhalt des AR2 gesichert werden (TAR2 #tmp_DW_AR2_Save) und danach wiederhergestellt (LAR2 #tmp_DW_AR2_Save).

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  9. #9
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Standard

    Ich mach's immer so:
    Code:
          TAR1  #SaveAR1
          TAR2  #SaveAR2
    
          LAR1  #SaveAR2
          L     P##pTCON_PAR  //ANY-Pointer am FB-IN
          +AR1  
          LAR2  P##pTCON_PAR_tmp //ANY-Pointer im Temp
    
          L     D [AR1,P#0.0]
          T     LD [AR2,P#0.0]
          L     D [AR1,P#4.0]
          T     LD [AR2,P#4.0]
          L     W [AR1,P#8.0]
          T     LW [AR2,P#8.0]
    
          LAR1  #SaveAR1
          LAR2  #SaveAR2
    Muss man eigentlich L DID [AR1,P#0.0] schreiben?
    Funktionieren tut's zumindest...
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  10. #10
    UsernameS7 ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    28.11.2014
    Beiträge
    11
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Die Sicherung des AR1 und AR2 mache ich am Anfang meiner Funktion und am Ende wird diese wiederhergestellt.

    Dann wäre es komplett so richtig:

    Code:
    //Sicherung
    TAR1  #SaveAR1
    TAR2  #SaveAR2
    
    
    // Quelle
    L     P##Datenholen            //relative Adresse #Datenholen in dieser Instanz (DI)
    TAR2                              //Transferiere Adressregister 2 in Akku 1
    UD    DW#16#FFFFFF                //Bereichskennung (DB) ausblenden
    +D                                //Addiere
    LAR1                              //Lade AR1 mit Inhalt von Akku 1: absolute Adresse #Datenholen im IDB (DI)
    
    LAR2  P##Quelle                   //Lade AR2: Adresse des TEMP-ANY
    L     DID [AR1,P#0.0]             //S7-code immer b#16#10 = 10hex + Datentyp + Wiederholfaktor
    T     LD [AR2,P#0.0]              //Transferiere nach Lokaldaten-Doppelwort Byte 0 von AR2
    L     DIW [AR1,P#4.0]             //Lade DB-Nummer
    T     LW [AR2,P#4.0]              //Transferiere nach Lokaldaten-Wort Byte 4 von AR2
    L     DID [AR1,P#6.0]             //Lade Bereichsadresse
    T     LD [AR2,P#6.0]              //Transferiere nach Lokaldaten-Doppelwort Byte 6 von AR2
    
    
    //Ziel
    LAR1  P##Ziel                     //Lade die Anfangsadresse des ANY-Pointers in AR1
    L     B#16#10                     //S7-code immer b#16#10 = 10hex
    T     LB [AR1,P#0.0]
    L     B#16#2                      //Datentyp: 02 = Byte
    T     LB [AR1,P#1.0]
    L     #Laenge                     //Länge der Daten bzw. Anzahl/Wiederholfaktor
    T     LW [AR1,P#2.0]
    L     DINO                        //DINO liest DBNR aus, wenn nicht benötigt: 0
    T     LW [AR1,P#4.0]
    L     B#16#84                     //Auswahl Eingänge bzw Speicherbereich: 84 = DB
    T     LB [AR1,P#6.0]
    L     B#16#0                      //Adressbelegung: 0 = 000
    T     LB [AR1,P#7.0]              //Adressformat:Byte.Bit wobei Byte aufgeteilt in Bit0-2 von 7. Byte
    L     P##OUT                      //Adressanfang (Zeiger), hier im Eingang       
    SLD   16                          //16mal Shift DWORD nach links (in Akku 1) damit Adressformat: .Bit = .000
    SRD   16                          //16mal Shift DWORD nach rechts (in Akku 1) damit Adressformat: .Bit = .000
    L     #Offset_Ziel                //Laden des Offsets
    +D    
    SLD   3                           //dreimal Shift nach links (in Akku 1) damit Adressformat: .Bit = .000
     T     LW [AR1,P#8.0]              //Adressformat: Byte.Bit wobei Byte in Bit0-7 von 8.Byte
    
    
    
    
    
    // Blockmove
    
          CALL  "BLKMOV"
           SRCBLK :=#Quelle
           RET_VAL:=#RET_VAL_Block
           DSTBLK :=#Ziel
          NOP   0
    
    
    //Wiederherstellen
    LAR1  #SaveAR1
    LAR2  #SaveAR2
    Oder habt ihr noch Verbesserungsvorschläge?
    Wieso funktioniert auch Ronins Beispiel ohne Bereichskennung ausblenden?
    Geändert von UsernameS7 (02.12.2014 um 11:40 Uhr)

Ähnliche Themen

  1. Index aus Array auslesen
    Von heri1980 im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 17.09.2010, 14:54
  2. Datenbereich über ANY Zeiger aus DB holen
    Von Temotec im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 21.06.2009, 21:42
  3. Float aus Byte-Array auslesen
    Von Joe im Forum Hochsprachen - OPC
    Antworten: 5
    Letzter Beitrag: 07.07.2008, 12:09
  4. Block_DB über zwei funktionen weiterreichen
    Von plant1 im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 13.08.2006, 15:17
  5. Wert mit Zeiger aus DB auslesen
    Von mst im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 03.03.2006, 20:20

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •