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

Ergebnis 1 bis 8 von 8

Thema: Verständniss zu Pointern

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

    Idee


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Mahlzeit,

    ich habe mir schon des öfteren hier Hilfen und Lösungen angelesen, komme aber nun bei Pointern an meine Grenze und muss daher einfach mal nachfragen. Ich bin in der Instandhaltung tätig und denke das ich mit der S7 soweit schon gut zurechtkomme. Letztes Projekt war eine S7 Erweiterung mit Schrittmotorsteuerung über Profibus, dabei konnte ich alle Fragen und Probleme durch Selbststudium lösen [hier war in der tat das Lesen der PB-Daten das kniffligste wenn man es noch nie gemacht hatte]. Bevorzugt nutze ich den KOP, AWL meide ich gerne wenn das Programm es zulässt.

    Was möchte ich nun:
    Ich will/muss eine Anlagenerweiterung aufbauen mit S7-300 für eine Teileerkennung. Dabei werte ich eine Kamera von oben und Sensorik von unten aus. Am Ende möchte ich für das erkennte Teil (ca 150 verschiedene) eine definierte Nummer haben mit der ich dann weiterarbeiten kann. Das ganze mit Step7 5.5

    Hier mal umrandet als Beispiel:
    Kamera gibt mir Typ A vor -> Wert 10 (Typen-Werte steigen in 10er Schritten -> 10, 20, 30...)
    Sensoren geben mir Form 2 -> Wert 2 (Form-Werte sind 0-9)
    -> ergibt Variante 12. Zu dieser Variante steht im DB 1 an 12. Stelle ein DBD -> DB1.DBD48 = 456789 -> Diese Zahl möchte ich als Ergebnis. (andere Varianten haben andere Zahlen)

    Also brauche ich ja "nur" einen Pointer auf das DBD48. Leider finde ich das Thema schwer zu verstehen weil da zuviele Zeichenkombinationen zusammenkommen.

    aber hier mal mein Stand wie ich glaube das es gehen müsste.
    Code:
    L DB2.DBD0                         -> da lege ich die Variante ab (direkt x4 gerechnet wegen DINT)
    SLD 3                                    -> Wenn ich es richtig verstanden habe schiebt es hier im Speicher etwas umher, das muss einfach so sein!??
    LAR1                                     -> schreibt das AR1, also eigendlich ist das schon der Pointer bzw die Adresse für den Pointer?
    
    AUF DB1                             -> DB erst aufrufen, muss so sein
    L DBD [AR1, P#0.0]            -> er lädt nun das DBD
    T DB2.DBD4                        -> da habe ich nun mein Ergebniss
    Fragen:
    Funktioniert das wirklich so einfach? Ich habe leider noch keine Hardware hier zum testen
    Geht es kürzer? Also kann ich in normalen DB-Aufrufen DB1.DBD[AR1,P#0.0] verwenden oder ists da tatsächlich das sauberste einen DB als Zwischenspeicher zu nehmen um von dort "normal" aufzurufen?
    kann ich, zur Verkleinerung auch Lokalworte dafür nutzen? (Also statt den DB2 einfach LDW0 und LDW4 nutzen)
    [zum verstehen]der P#0.0 (weiterschieben, eher in Verbindung mit Schleife/Zähler?) muss immer dabei sein? Und muss immer zum Typ passen? (DBD P#0.3 -> Stopp, DBB p#0.3 -> Stopp, ...)
    wenn ich den DB auchnoch Variabel machen möchte.. wäre es any-Zeiger? Da ist ja gar nicht mehr zu erkennen warum da was passiert..

    Ich hoffe das ist soweit verständlich

    mfg Beka
    Zitieren Zitieren Verständniss zu Pointern  

  2. #2
    Registriert seit
    21.11.2014
    Beiträge
    228
    Danke
    7
    Erhielt 30 Danke für 28 Beiträge

    Standard

    Ich kenne ja deine Rahmenbedingungen nicht, aber ich denke ich würde so vorgehen:

    Zieldaten dint
    Kamera int
    Sensor int
    Add int (als Zwischenergebnis)

    //DB enthält die Daten
    Data Array [0..149] of Dint

    //Deine Sensoren geben dir
    Add:=Sensor+Kamera

    Zieldaten:=DB.Data[Add]

    Wäre das nicht einfacher?

    [Muss dazu sagen: ich bin ne Niete in AWL ]

  3. Folgende 2 Benutzer sagen Danke zu Christmaspoo für den nützlichen Beitrag:

    Bekanor (15.04.2016),ThorstenSt (14.04.2016)

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

    Standard

    Zitat Zitat von Bekanor Beitrag anzeigen
    Fragen:
    Funktioniert das wirklich so einfach? Ich habe leider noch keine Hardware hier zum testen
    Sollte so funktionieren. Obwohl ich nicht weiß was beim "direkt x4 gerechnet" DB2.DBD0 gemeint ist.
    In DB2.DBD0 muss einfach die Byte-Adresse stehen auf die du zugreifen willst.
    Zitat Zitat von Bekanor Beitrag anzeigen
    Geht es kürzer? Also kann ich in normalen DB-Aufrufen DB1.DBD[AR1,P#0.0] verwenden oder ists da tatsächlich das sauberste einen DB als Zwischenspeicher zu nehmen um von dort "normal" aufzurufen?
    Möglich wäre...
    Code:
    L   P#30.0    //Pointer direkt laden
    T   LD0        //hier keine DB-Variable verwenden
    
    AUF DB1
    L   DBD[LD0]
    
    //------------------------------------------------------------
    
    L   L#30    //gleichen Pointer selbst erstellen
    SLD 3
    T   LD0        //hier keine DB-Variable verwenden
    
    AUF DB1
    L   DBD[LD0]
    Zitat Zitat von Bekanor Beitrag anzeigen
    kann ich, zur Verkleinerung auch Lokalworte dafür nutzen? (Also statt den DB2 einfach LDW0 und LDW4 nutzen)
    Das hat sogar Vorteile weil...
    Code:
    L   L#30
    SLD 3
    LAR1
    
    AUF DB1
    L   DBD[AR1,P#0.0]    //lädt DB1.DBD30
    T   DB2.DBD30
    L   DBD[AR1,P#0.0]    //lädt jetzt DB2.DB30 weil wir inzwischen auf DB2 zugegriffen haben.
                                    //verwendet man Lokaldaten wird das DB-Register nicht verändert
    Zitat Zitat von Bekanor Beitrag anzeigen
    [zum verstehen]der P#0.0 (weiterschieben, eher in Verbindung mit Schleife/Zähler?) muss immer dabei sein? Und muss immer zum Typ passen? (DBD P#0.3 -> Stopp, DBB p#0.3 -> Stopp, ...)
    Wenn du einen Pointer hast der hinten noch einen Wert bei der Bitadresse hat, also z.B.: P#30.3 und du versuchst damit ein Byte zu laden, dann wäre dass das selbe als würde man L DB2.DBB30.3 schreiben -> geht nicht.

    Schau dir mal das FAQ zum Thema Pointer von Volker an. Da steht vieles (auch das SLD3) erklärt.
    Pointer Zeiger FIFO LIFO
    Zitat Zitat von Bekanor Beitrag anzeigen
    wenn ich den DB auchnoch Variabel machen möchte.. wäre es any-Zeiger? Da ist ja gar nicht mehr zu erkennen warum da was passiert..
    Geht...
    Code:
    L   10
    T   LW0
    AUF [LW0]    //Das geht aber nur mit einem wort aus den Lokaldaten oder Merkern.
    In SCL geht manches, sofern man z.B. ein Array verwenden kann, oft um einiges leichter. Wie wild irgendwo in DBs herumzufuchteln bleibt aber AWL vorbehalten.
    Geändert von RONIN (14.04.2016 um 18:56 Uhr)
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  5. Folgender Benutzer sagt Danke zu RONIN für den nützlichen Beitrag:

    Bekanor (15.04.2016)

  6. #4
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.284
    Danke
    932
    Erhielt 3.320 Danke für 2.682 Beiträge

    Standard

    Du hast ein ARRAY OF DINT und willst auf ein bestimmtes Element des Arrays zugreifen, dessen Position im Array variabel berechnet werden soll.

    Berechne zunächst, auf welches Element des Arrays Du zugreifen mußt, wenn ich richtig verstanden habe dann ungefähr so:
    Index := (Kamerawert * 10) + Sensorwert ; (wenn Kamerawert 0, 1, 2, 3, ...)
    oder
    Index := Kamerawert + Sensorwert ; (wenn Kamerawert 0, 10, 20, 30, ...)

    Nun greife auf das Element ARRAY[Index] zu. Das geht bei der S7-300 aber leider nur in SCL so übersichtlich.

    In AWL muß man selber die Adresse ausrechnen, an der das Element liegt:
    Adresse := Index * 4 * 8 + Arrayanfang ;
    "* 4" weil die Elemente 4 Bytes (= 1 DINT) groß sind
    "* 8" weil eine Bitadresse P#Byte.0 angegeben werden muß
    "+ Arrayanfang" falls das Array im DB nicht bei DBX0.0 beginnt, dann z.B. P#100.0 addieren für Array ab DBX100.0

    "*4" und "*8" kann man zusammenfassen zu "*32" was einem Bit-Schieben um 5 Stellen nach links entspricht, wofür man "SLD 5" schreiben kann.
    ("SLD 1" = *2 | "SLD 2" = *4 | "SLD 3" = *8 | "SLD 2" + "SLD 3" = "SLD 5" = *32)

    Dadurch kann Dein AWL-Programm z.B. so aussehen:
    Code:
    L #index            //(TEMP, INT)
    SLD 5               //Array-Index --> Adresse P#
    L P#0.0             //Anfangsadresse des Array im DB
    +D                  //dazu
    LAR1                //berechnete Adresse in AR1 laden
    
    AUF "DB1"
    L DBD [AR1, P#0.0]  //DINT aus "DB1".MyArray[#index] lesen
    T "DB2".MeinWert
    Oder etwas besser lesbar so:
    Code:
    L #index            //(TEMP, INT)
    SLD 5               //Array-Index --> Adresse P#
    L P#0.0             //Anfangsadresse des Array im DB
    +D                  //dazu
    T #tmpAdresse       //berechnete Adresse in TEMP-DWORD speichern
    
    AUF "DB1"
    L DBD [#tmpAdresse] //DINT aus "DB1".MyArray[#index] lesen
    T "DB2".MeinWert

    "L DBD [#tmpAdresse]" = speicherindirekte Adressierung, weil der Pointer (die Adresse) im Speicher liegt (Speicher kann L, M, DB sein)

    "L DBD [AR1, P#0.0]" = registerindirekte Adressierung, weil der Pointer (die Adresse) in einem Adressregister ARx liegt
    Statt dem P#0.0 kann noch ein zusätzlicher Versatz/Offset angegeben werden. Nützlich wenn man in AR1 die Anfangsadresse einer Struktur hält und nacheinander auf mehrere Elemente dieser Struktur zugreifen will.

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

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  7. Folgender Benutzer sagt Danke zu PN/DP für den nützlichen Beitrag:

    Bekanor (15.04.2016)

  8. #5
    Bekanor ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    14.04.2016
    Beiträge
    11
    Danke
    6
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Soo, vor so etwas hatte ich Angst, da glaubt man es verstanden zu haben, und dann wird's doch nochmal kompliziert..


    Zitat Zitat von PN/DP Beitrag anzeigen
    "* 8" weil eine Bitadresse P#Byte.0 angegeben werden muß
    da hatte ich schon den ersten Aufhänger. Verstehe nicht wieso *8 wenn ich garnicht bis auf die Bit-Ebene runter will?

    Code:
     L #index            //(TEMP, INT)
     SLD 5               //Array-Index --> Adresse P#
     L P#0.0             //Anfangsadresse des Array im DB
     +D                  //dazu
     LAR1                //berechnete Adresse in AR1 laden
    
     AUF "DB1"
     L DBD [AR1, P#0.0]  //DINT aus "DB1".MyArray[#index] lesen
     T "DB2".MeinWert
    nächster Treffer. Da dachte ich SLD3 muss sein, okay.. Muss nicht, kann auch noch Variieren. Das Ganze liegt nun am Speicheraufbau? SLD5 weil hier nur noch ein INT geladen wird?
    Lade ich nun ein Int, schreibt er es in Byte 0+1. Damit sie für den Pointer an der richtigen Stelle liegen (was Byte 4+5 sein sollten?) müssen sie um 32 Bits geschoben werden. (Das "5 Stellen" ist also eigendlich nur 4 Bytes?)
    Soweit richtig verstanden?
    Wieso schiebt er nun abernicht in die Bitadresse rein (Wenn ich das Bild Pointer-Aufbau so sehen..? Pointer Zeiger FIFO LIFO), also in die letzten 3 Bits?


    Ich möchte ja schon gern das mein Programm später läuft, vor allem aber möchte ich verstehen warum
    Da raucht ja echt nur der Schädel.

    gutes Nächtle
    Beka
    Geändert von Bekanor (14.04.2016 um 21:45 Uhr)

  9. #6
    Registriert seit
    24.10.2007
    Ort
    Niederlande
    Beiträge
    673
    Danke
    22
    Erhielt 143 Danke für 135 Beiträge

    Standard

    Zitat Zitat von Bekanor Beitrag anzeigen
    Soo, vor so etwas hatte ich Angst, da glaubt man es verstanden zu haben, und dann wird's doch nochmal kompliziert..



    da hatte ich schon den ersten Aufhänger. Verstehe nicht wieso *8 wenn ich garnicht bis auf die Bit-Ebene runter will?


    nächster Treffer. Da dachte ich SLD3 muss sein, okay.. Muss nicht, kann auch noch Variieren. Das Ganze liegt nun am Speicheraufbau? SLD5 weil hier nur noch ein INT geladen wird?
    Lade ich nun ein Int, schreibt er es in Byte 0+1. Damit sie für den Pointer an der richtigen Stelle liegen (was Byte 4+5 sein sollten?) müssen sie um 32 Bits geschoben werden. (Das "5 Stellen" ist also eigendlich nur 4 Bytes?)
    Soweit richtig verstanden?
    Wieso schiebt er nun abernicht in die Bitadresse rein (Wenn ich das Bild Pointer-Aufbau so sehen..? Pointer Zeiger FIFO LIFO), also in die letzten 3 Bits?


    Ich möchte ja schon gern das mein Programm später läuft, vor allem aber möchte ich verstehen warum
    Da raucht ja echt nur der Schädel.

    gutes Nächtle
    Beka
    Wenn Sie ein pointer adresse berechne von ZB DBD40 muste Sie das anzahl bits zahlen ab DBX0.0 fur DBD 40 ist das 40(Byte) * 8 = 320 Ein pointeradresse ist immer ein DWord
    Wenn Sie z.b. LD0 die name Adresse gibt format DWORD.

    Wenn Ihre index = 10 und Sie muste Das artikel nr aus ein DWord laden muste Sie fur Jede artikel die index mit 32(bit) multiplizieren
    die Code wurde dann
    Code:
    L Index       //=10
    SLD5         //= *32
    T Adresse   //  = 320  
    AUF DB1
    L DBD[Adresse]     // L DBD40

  10. Folgender Benutzer sagt Danke zu JoopB für den nützlichen Beitrag:

    Bekanor (15.04.2016)

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

    Standard

    Nu hab ich es verstanden.

    Ich hatte es mir wohl zu Bildlich vorgestellt.
    *falsch* Wenn ich "L DBD [AR1, p#0.0]" habe soll halt in der Klammer nicht "40" rauskommen.
    *richtig* DBD gibt die Länge der Daten an die gelesen wird, der Pointer zeigt das erste Bit. Hmm.. eigentlich dann doch gar nicht so schwer.

    Ich konnte es gerade auch mal an einer Anlage testen, werde wohl auch den DB variabel aufrufen. Kamera ruft den DB auf, Sensoren zeigen die entsprechende Zeile. Wird übersichtlicher, und wenn es später weitere Typen gibt, ist eine Erweiterung leichter.

    vielen Dank für die Hilfe

    mfg Beka

  12. #8
    Registriert seit
    24.10.2007
    Ort
    Niederlande
    Beiträge
    673
    Danke
    22
    Erhielt 143 Danke für 135 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Wenn du die DB indirekt aufrufen wolh mussen Sie das DB nr in ein int kopiëren z.b. lokal variabele DB_nr. Und die DB machen Sie actief mit AUF DB [DB_nr]


    Verstuurd vanaf mijn GT-I9301I met Tapatalk
    Geändert von JoopB (15.04.2016 um 17:50 Uhr)

Ähnliche Themen

  1. verständniss Probleme VB.NET > S7ONLINE
    Von Mahon im Forum Hochsprachen - OPC
    Antworten: 13
    Letzter Beitrag: 02.09.2011, 21:35
  2. Problem mit Verständniss für Programmstruktur
    Von Peter_AUT im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 05.08.2011, 19:15
  3. Frage verständniss Start / Stop Taster
    Von maxi im Forum Maschinensicherheit - Normen und Richtlinien
    Antworten: 7
    Letzter Beitrag: 12.11.2008, 19:05
  4. Falsches Verständniss von DB's
    Von MSP im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 10.07.2005, 19:13
  5. Fragen zu Pointern
    Von INST im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 28.05.2004, 19:20

Lesezeichen

Berechtigungen

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