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

Ergebnis 1 bis 6 von 6

Thema: Funktion FC mit ANY-Pointer zur Steuerung/Auslesen der Peripherie

  1. #1
    Registriert seit
    23.10.2015
    Ort
    Hessen
    Beiträge
    51
    Danke
    12
    Erhielt 1 Danke für 1 Beitrag

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo alle zusammen,

    ich habe mal wieder ein kleines Anliegen und hoffe ich bekomme Hilfestellung von euch:

    Funktion FC: dient der Steuerung der Profibus/Profinet Antriebe und wurde auf das Standarttelegramm 1 PZD2/2 angepasst. Die Antriebe haben dabei separate DBs.
    Über den nutzen von FCs und FBs mit IDBs lässt sich natürlich streiten, nur hier bleibt es beim FC.

    Nun soll an einer bestehenden Anlage, die Funktion auf das Telegramm 20 angepasst werden und entsprechend PZD2/6 übergeben/ausgelesen werden.

    Daher habe ich in der Funktion unter TEMP folgende Variablen/Strukturen:
    Name
    Datentyp
    Adresse
    E_A_Adresse DWord 0.0
    SEND Struct 4.0
    REC Struct 8.0
    HM_scale_value_setpoint Real 20.0
    ... ... ...
    Ziel Any 48.0
    Quelle Any 58.0













    Ursprünglicher COde zum auslesen der Daten der Peripherie:
    Code:
     L     #HW_Konfig_E_A_Adresse      // Adresse laut HW-Konfig im Integer-Format
          SLD   3                           // Konvertierung ins Pointerformat: 3 Stellen nach links schieben 
          T     #Adresse_E_A                // Adresse in Doppelwort
    Code:
     L     PED [#Adresse_E_A]          // Prozessdaten vom Antrieb empfangen
          T     LD     8                    // Transferiere in das Lokaldaten-Doppelwort LD
    Hier stellt sich die Frage wie ich mehrere Wörter (6 PZD) empfangen soll,wenn PED nur ein Doppelwort (zwei Wörter) überträgt?!

    Ich dachte mir durch die Verwendung von ANY-Pointern könnte ich das etwas besser und variable gestalten, da ich ja somit nur die Länge der Daten ändern muss um den Baustein für weitere Telegramme zu ändern. Anschließend werden mit einem Blockmove die Daten vom Antrieb in den Tempbereich des FC kopiert.
    Die Vorlage der Anypointer habe ich hier aus dem Forum und hoffe das ich diese richtig umgeändert habe:
    Code:
      L     6                           //Anzahl bzw. Länge der Wörter
          T     #Laenge
    
    // Erstellung des Quell Pointers
    
          L     P##Quelle
          LAR1                              //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#4                      //Datentyp: 04 = WORD
          T     LB [AR1,P#1.0]
          L     #Laenge                     //Länge der Daten bzw. Anzahl/Wiederholfaktor
          T     LW [AR1,P#2.0]
          L     0                           //Nummer des DB's, wenn nicht benötigt: 0
          T     LW [AR1,P#4.0]
          L     B#16#80                     //Auswahl Speicherbereich: 80 = P (Peripherie)
          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     #Adresse_E_A                //Adressanfang (Zeiger), hier im Peripherieeingang       
          SLD   3                           //dreimal Shift nach links (in Akku 1) damit Adressformat: .Bit = .0
          T     LW [AR1,P#8.0]              //Adressformat: Byte.Bit wobei Byte in Bit0-7 von 8.Byte
    
    
    // Erstellung des Ziel Pointers
    
          L     P##Ziel
          LAR1                              //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#4                      //Datentyp: 04 = WORD
          T     LB [AR1,P#1.0]
          L     #Laenge                     //Länge der Daten bzw. Anzahl/Wiederholfaktor
          T     LW [AR1,P#2.0]
          L     0                           //DINO liest DBNR aus, wenn nicht benötigt: 0
          T     LW [AR1,P#4.0]
          L     B#16#86                     //Auswahl Speicherbereich: 86 = Lokaldaten L-Stack
          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##REC                      //relative Adresse/Adressanfang der Struktur (Zeiger)  
          SLD   8                           //8mal Shift DWORD nach links (in Akku 1) damit Bereichskennung ausblenden
          SRD   8                           //8mal Shift DWORD nach rechts (in Akku 1) damit Bereichskennung ausblenden
          SLD   3                           //dreimal Shift nach links (in Akku 1) damit Adressformat: .Bit = .0
          T     LW [AR1,P#8.0]              //Adressformat: Byte.Bit wobei Byte in Bit0-7 von 8.Byte
    
    
    // Wiederherstellen der Adressregister
          LAR1  #SaveAR1                    //Wiederherstellen des AR1
          LAR2  #SaveAR2                    //Wiederherstellen des AR2 für Zugriff auf Instanzvariable
    
        CALL  "BLKMOV"
           SRCBLK :=#Quelle
           RET_VAL:=#RET_VAL_BLKMOV
           DSTBLK :=#Ziel
          NOP   0
    Würde dies funktionieren oder hättet ihr eine bessere Idee zum Auslesen der Daten?
    Geändert von SPS-EK (24.11.2015 um 16:18 Uhr)
    Zitieren Zitieren Funktion FC mit ANY-Pointer zur Steuerung/Auslesen der Peripherie  

  2. #2
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.192
    Danke
    925
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    Zitat Zitat von SPS-EK Beitrag anzeigen
    Ursprünglicher COde zum auslesen der Daten der Peripherie:
    Code:
     L     #HW_Konfig_E_A_Adresse      // Adresse laut HW-Konfig im Integer-Format
          SLD   3                           // Konvertierung ins Pointerformat: 3 Stellen nach links schieben 
          T     #Adresse_E_A                // Adresse in Doppelwort
    Code:
     L     PED [#Adresse_E_A]          // Prozessdaten vom Antrieb empfangen
          T     LD     8                    // Transferiere in das Lokaldaten-Doppelwort LD
    Hier stellt sich die Frage wie ich mehrere Wörter (6 PZD) empfangen soll,wenn PED nur ein Doppelwort (zwei Wörter) überträgt?!
    Code für 6 Words:
    Code:
          L     #HW_Konfig_E_A_Adresse      // Adresse laut HW-Konfig
          SLD   3                           // Konvertierung ins Pointerformat: Adr --> P#Adr.0
          LAR1
    
          LAR2  P##REC                      // Anfangsadresse der Struktur REC in TEMP
    
          L     PED [AR1, P#0.0]            // Prozessdaten vom Antrieb lesen
          T     D [AR2, P#0.0]              // Transferiere Words 1+2 in die Struktur REC
          L     PED [AR1, P#4.0]            // Prozessdaten vom Antrieb lesen
          T     D [AR2, P#4.0]              // Transferiere Words 3+4 in die Struktur REC
          L     PED [AR1, P#8.0]            // Prozessdaten vom Antrieb lesen
          T     D [AR2, P#8.0]              // Transferiere Words 5+6 in die Struktur REC
    Code:
    //geht beides:
          T     D [AR2, P#8.0]              // Bereichsübergreifende, registerindirekte Adressierung
          T     LD [AR2, P#8.0]             // Bereichsinterne, registerindirekte Adressierung
    Die Adressregister AR1 und AR2 müssen nicht gesichert werden.

    Wie ist die Konsistenz der 6 PZD eingestellt?
    Wenn "Gesamt", dann geht PED-Zugriff nicht, dann muß SFC14 "DPRD_DAT" zum Lesen aus der Peripherie benutzt werden.

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

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  3. #3
    SPS-EK ist offline Benutzer
    Themenstarter
    Registriert seit
    23.10.2015
    Ort
    Hessen
    Beiträge
    51
    Danke
    12
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hallo Harald,

    Konsistenz ist auf "Gesamte Länge" eingestellt. Muss man SFC14 nutzen oder klappt das nicht auch mit den zusammengesetzten Anypointern?
    Denn genau das wollte ich umgehen, dass ich eine Funktion habe die immer funktioniert, egal was eingestellt ist. Daher auch der Gedanke mit dem Quellpointer der die 6 Wörter lädt.
    Durch die Längen angabe könnte ich so immer auf ein andere Telegramm switchen und es würde immer funktionieren oder nicht?

    Wieso machst du den Quellpointer so kurz?
    Ist es denn so falsch wie ich es gemacht habe?
    Wieso müssen die ARs nicht gesichert? Ich dachte wenn man die Adressregister überschreibt dann sollte man diese wieder herstellen.

    Sorry, für die vielen Fragen aber naja so gut kenn ich die Materie ja (noch) nicht

  4. #4
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.192
    Danke
    925
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    Zitat Zitat von SPS-EK Beitrag anzeigen
    Konsistenz ist auf "Gesamte Länge" eingestellt. Muss man SFC14 nutzen oder klappt das nicht auch mit den zusammengesetzten Anypointern?
    Man muß SFC14 nutzen. Das selbstgeschriebene Programm kann nicht bei Gesamt-Konsistenz 6 Wörter aus der Peripherie lesen, das kann nur das Betriebssytem. Wenn man es trotzdem versucht, dann liefern die Lesezugriffe auf die PED... immer 0 - probiere es aus!

    Alternative: lege die E/A-Adressen der Antriebe ins Prozessabbild (ggf. Größe des Prozessabbilds vergrößern in den CPU-Eigenschaften), dann kannst Du mit einzel-Zugriffen oder BLKMOV die E/A umkopieren.


    Denn genau das wollte ich umgehen, dass ich eine Funktion habe die immer funktioniert, egal was eingestellt ist. Daher auch der Gedanke mit dem Quellpointer der die 6 Wörter lädt.
    Durch die Längen angabe könnte ich so immer auf ein andere Telegramm switchen und es würde immer funktionieren oder nicht?
    Ja genau, das will jeder - die eierlegende Wollmilchsau die ohne Nachdenken automatisch alles richtig macht, so daß die nächste Maschine vom Azubi programmiert werden kann und man selber überflüssig geworden ist...
    Automatisch mit verschiedenen PZD-Längen arbeiten ist nicht mit der Längenangabe alleine gelöst. Wie ändert sich automatisch die Größe der Struktur REC? Der Inhalt der Zusatz-Wörter kann verschieden sein - wie soll das Programm das erkennen? ...? Es erfordert sowieso Fallunterscheidungen.


    Wieso machst du den Quellpointer so kurz?
    Was heißt "kurz"?
    Der Code kopiert einfach auf kürzestem Weg 6 Wörter von einer vorgegebenen Anfangsadresse. Wozu das ganze noch mit ANY-Pointern künstlich aufblähen?


    Ist es denn so falsch wie ich es gemacht habe?
    Es ist sinnlos weil BLKMOV kann nicht in/aus Peripherie kopieren.


    Wieso müssen die ARs nicht gesichert? Ich dachte wenn man die Adressregister überschreibt dann sollte man diese wieder herstellen.
    Es ist überflüssig. Es bringt nichts.
    Nur in FB enthält das AR2 einen Wert (Offset dieser Multiinstanz im Mutter-IDB), den man nicht verlieren darf wenn man auf Instanzvariablen zugreifen will. In allen anderen Fällen erwartet das Betriebssystem keine bestimmten Werte in den Adressregistern und initialisiert diese bei Bedarf vor Verwendung - ohne Rücksicht darauf, was da schon drin steht - man kann es selber genauso machen. Insbesondere darf man nicht davon ausgehen, daß nach Aufruf irgendeines anderen Bausteins bei der Rückkehr in den Adressregistern noch die Werte von vor dem Aufruf drinstehen (z.B. weil das Betriebssystem vielleicht schon AR1 für die Parameterübergabe benutzt hat). Nur derjenige, der die Adressregister nutzt, sollte diese sichern, wenn er eigene Werte darin behalten will.

    Bei welchen Operationen überschreibt STEP 7 den Akku-Inhalt bzw. den Inhalt von Registern?
    Siehe auch die STEP7 Hilfe "Hinweise zur Änderung von Register-Inhalten" und "Vermeiden von Fehlern beim Aufrufen von Bausteinen"

    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
    06.10.2003
    Beiträge
    3.412
    Danke
    451
    Erhielt 506 Danke für 408 Beiträge

    Standard

    Hallo EK,

    Zitat Zitat von SPS-EK Beitrag anzeigen
    .. Konsistenz ist auf "Gesamte Länge" eingestellt. Muss man SFC14 nutzen ..?
    Natürlich verwendet man hier die SFC14/15. Hast du mal probiert, auf die Peripherieadressen der konsistenten Bereiche direkt mit Ladebefehlen zuzugreifen? Es würde mich mal interessieren, ob das wirklich nicht geht. Ich dachte immer, es müsste prinzipiell auch möglich sein, dann natürlich mit Verlust der Gesamt-Konsistenz. Möglicherweise habe ich dies jedoch selbst noch nie probiert.

    Es gibt aber einen Fall, wo eine solche Funktion durchaus Sinn macht, und zwar bei nichtkonsistenten Datenblöcken im Peripheriebereich. Diese kann man weder mit der SFC14/15 noch mit der SFC20 übertragen. Dazu kann man den Ablagebereich im DB als ANY-Pointer der FC übergeben, sowie die Adresse des Peripheriebereiches lediglich als INT oder WORD. Die Daten sollten im DB sinnvollerweise strukturiert angelegt sein. In der FC zerpflückt man den ANY und gewinnt daraus den DB und die Datenlänge in Byte. Mit diesen Informationen kopiert man byteweise in einer Schleife die Daten, vorzugsweise in SCL.

    Gruß, Onkel
    Es gibt viel mehr Leute, die freiwillig aufgeben, als solche, die echt scheitern.
    Henry Ford

  6. #6
    SPS-EK ist offline Benutzer
    Themenstarter
    Registriert seit
    23.10.2015
    Ort
    Hessen
    Beiträge
    51
    Danke
    12
    Erhielt 1 Danke für 1 Beitrag

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Harald,

    Ok, ich muss mir das mal mit dem Prozessabbild anschauen und anpassen.
    Ausprobieren kann ich gerade nicht, gerade den seltenen Fall das keine Anlage vor Ort ist und die Testmittel lassen noch zu wünschen übrig.

    Naja, wir sind ja im Bereich der Automatisierung also wenn ich so eine Funktion programmier, dann auch entsprechend weitgehend.
    Die Wörteranzahl könnte man ja durch einen Übergabeparameter so realisieren, dass man dort angibt welches Telegramm man benutz und in der Funktion wird entsprechend die Datenlänge des ANY-Pointers geändert. Ähnlich wie mit Angabe der EA-Adresse nur dann mit Fallunterscheidung in der Funktion. Problematischer wäre es bei den 32Bit Wörter, nur bei uns wird bisher nur Telegramm 1, 20 und eventuell zukünftig 350 benutzt. Und ob die Strukturen beschrieben werden oder nicht macht ja im Grunde nichts aus, solange diese angelegt sind.
    Die Struktur könnte man größt möglich dimensionieren und entsprechend vorbelegen. Über die Angabe welches Telegramm werden dann auch nur die entsprechenden Wörter kopiert. So ähnlich dachte ich es mir oder habe ich ein Denkfehler?

    Hallo Onkel Dagobert,
    Also das PED mit zwei Wörtern kann ich logischer weise auslesen und laut einer alten Funktion wurde die EAdresse um 4 erhöhrt um somit zb den Stromistwert aus dem FU auszulesen und das alles mit Lade-/Transferbefehlen. Was anderes Macht der MOVE bzw Blockmove ja auch nicht. Theoretisch müsste es gehen, aber wie Harald schon schreibt könnte es daran scheitern. Mir wäre der ANYPOINTER halt dennoch lieber weil ich so wie schon geschrieben eine Fallunterscheidung zwischen den Telegrammen machen kann und die Funktion entsprechend die Wörter ausliest.
    Geändert von SPS-EK (25.11.2015 um 11:51 Uhr)

Ähnliche Themen

  1. Antworten: 7
    Letzter Beitrag: 12.06.2015, 16:57
  2. Peripherie Eingänge auslesen
    Von Bertman im Forum Simatic
    Antworten: 9
    Letzter Beitrag: 31.03.2010, 13:43
  3. Länge eines String mit der LEN-Funktion auslesen
    Von baggerandy im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 10.04.2009, 16:13
  4. Antworten: 2
    Letzter Beitrag: 30.08.2006, 10:00
  5. Antworten: 1
    Letzter Beitrag: 28.08.2006, 20:35

Lesezeichen

Berechtigungen

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