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

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Var_IN als Pointer verwenden?

  1. #1
    Registriert seit
    09.12.2011
    Beiträge
    52
    Danke
    2
    Erhielt 4 Danke für 4 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Leute,

    ich versuche gerade eine Adresse an das Programm 'Movitrac' zu übergeben:

    G01.PNG

    Wie muss ich denn nun Adr_IN innerhalb des Programms deklarieren?
    Folgende Fehlermeldung kommt momentan:
    "Unzulässiger Typ für Eingang 'Adr_IN' von 'Movitrac': Kann 'Byte' nicht in 'POINTER TO BYTE' konvertieren.

    Der Inhalt des Programms ist noch etwas spärlich:

    VAR_INPUT
    xFreigabe: BOOL;
    xRechts_links: BOOL;
    wGeschwindigkeit: WORD;
    Adr_IN: POINTER TO BYTE;
    END_VAR
    VAR_OUTPUT
    wStatus: WORD;
    wFehlercode: WORD;
    END_VAR
    VAR_IN_OUT
    Adr_OUT: POINTER TO BYTE;
    END_VAR

    G02.PNG



    Viele Grüße,

    Tom
    Zitieren Zitieren Var_IN als Pointer verwenden?  

  2. #2
    Registriert seit
    09.11.2007
    Ort
    Rhein Main (Darmstadt)
    Beiträge
    663
    Danke
    61
    Erhielt 112 Danke für 80 Beiträge

    Standard

    Soweit ich weiss, ist der Standard einen "Pointer" zu übergeben, die Variable in einem FB als VAR_IN_OUT zu deklarieren.

    Dann kommt er rüber als REFERENZ, das ist so in etwa eine Adresse, die man nicht verändern kann. Der Zugriff ist dann schon dereferenziert!

    Übrigens ist in der IEC die ganze Pointerei unerwünscht, nicht genau spezifiziert und kann von einem Service Pack zum nächsten schon anders implementiert sein. Kurz Finger davon lassen oder man weiss genau, was da gemacht wird.
    Als Freelancer immer auf der Suche nach interessanten Projekten.

  3. #3
    Registriert seit
    24.02.2009
    Beiträge
    1.242
    Danke
    23
    Erhielt 276 Danke für 235 Beiträge

    Standard

    Wenn der FB einen Pointer to Byte erwartet, dann übergibst du ihm einfachen einen Pointer to Byte.

    evtl. so:

    varIn AT%IB6000 :Byte;
    varOut AT%QB6000 :Byte;

    ptbIn :Pointer_to_Byte;
    ptbOut :Pointer_to_Byte;

    ptbIn := ADR(varIn);
    ptbOut := ADR(varOut);

    Adr_In := ptbIn;
    Adr_Out := ptbOut;



    Einen Pointer als VAR_IN_OUT zu deklarieren macht wenig Sinn.
    In dem du Pointer übergibst, werden die Variablen auf die gezeigt wird automatisch zu IN_OUT, da der FB direkt von der Adresse lesen und auf ihr Schreiben kann.
    => Call by Referenz.
    VAR_IN_OUT macht nichts anderes als einen Pointer in den FB zu übergeben. Du hast jetzt also einen Pointer auf einen Pointer.
    Pointer immer als Input, ausser du willst die Pointer selber verändern und nicht die Variablen auf die sie zeigen.

    EDIT:
    @RobiHerb
    Wenn man Puffer mit dynamischer Größe benötigt (viele universell einsetzbare Kommunikationsbausteine) oder man Input und Output - Variablen von FBs wärend der Laufzeit ändern will, gehts ohne Pointer schlecht.

    Wo man sie aber nicht zwingend braucht, sollte man Pointer aber so gut es geht vermeiden. Sie erschweren die Fehlersuche im Programm (die fiesesten Fehler die ich bei mir jemals im Code hatte, wurden durch falsche Adressberechnungen hervorgerufen) und verlangen nach sehr viel Fingerspitzengefühl.
    Geändert von MasterOhh (23.02.2016 um 10:36 Uhr)
    Sänd from mei Kombjudder mitse Dastadurr.

  4. #4
    Registriert seit
    26.01.2013
    Ort
    Hannover
    Beiträge
    99
    Danke
    2
    Erhielt 15 Danke für 10 Beiträge

    Standard

    Moin,
    wenn ich das richtig sehe in deinem Bild 1, musst du natürlich einen Pointer an den FB übergeben und nicht ein Byte (%IB6000)
    Gruß
    Holger

  5. #5
    Booner ist offline Benutzer
    Themenstarter
    Registriert seit
    09.12.2011
    Beiträge
    52
    Danke
    2
    Erhielt 4 Danke für 4 Beiträge

    Standard

    Hei,

    oha! Schon mal vielen Dank für die ganzen Hinweise! Die ich zum Teil erst noch verstehen muss...
    Da habe ich wieder was gelernt:

    Wenn ich "%IB6000" an den Eingang schreibe, übergibt er dessen Wert.
    Ich habe es nun mit "ADR(
    %IB6000)" getestet. Bin aber noch nicht weiter.

    Mein eigentliches Ziel ist es, in meinem Programm die Werte aus der CanOpen Kommunikation zu verarbeiten:
    Dazu will ich eigentlich nur die erste Adresse übergeben und die anderen zwei dann "berechnen". Habe aber noch keine Ahnung wie das geht. Gute Voraussetzung oder?
    G03.PNG

    Offensichtlich habe ich da auch noch die falsche Adresse (%QB6000) erwischt? Richtig wäre wohl die %QW3000?
    Was bedeutet denn die %QB6000?

    Nochmals ganz herzlichen Dank für die Unterstützung!


    Grüße,

    Tom
    Geändert von Booner (23.02.2016 um 11:15 Uhr)

  6. #6
    Registriert seit
    09.11.2007
    Ort
    Rhein Main (Darmstadt)
    Beiträge
    663
    Danke
    61
    Erhielt 112 Danke für 80 Beiträge

    Standard

    Wie ich schon sagte oben, Pointer gibt es, aber das wird nicht empfohlen.

    Mein Ansatz wäre:

    Kopieren der Eingangsdaten in ein Array OF BYTE,
    Übergabe dieses Arrays an den FB,
    Auswertung der Kopie im FB,
    ggf. Rückgabe eines Ergebnisses in weiteren Variablen.

    Hiermit ist die Peripherie vom SPS internen Procedere entkoppelt.
    Als Freelancer immer auf der Suche nach interessanten Projekten.

  7. #7
    Booner ist offline Benutzer
    Themenstarter
    Registriert seit
    09.12.2011
    Beiträge
    52
    Danke
    2
    Erhielt 4 Danke für 4 Beiträge

    Standard

    Hei,

    okay, empfohlen wird es nicht. Allerdings möchte ich mich trotzdem ein wenig einarbeiten in die Pointerei, weil ich das auch öfters in fertigen Programmen sehe und dann verstehen will, was da passiert.

    Wenn ich einen Pointer auf die Adresse %QW3000 habe, was muss ich denn der Adresse addieren, um auf %QW3001 zu kommen?
    Ich dachte da an z.B. "16#FFFFFFFE"

    EDIT: Hab gerade rausgefunden, dass "2" addiert wird. Warum genau 2? Weiß das jemand?


    Grüße,

    Tom
    Geändert von Booner (23.02.2016 um 14:24 Uhr)

  8. #8
    Registriert seit
    09.11.2007
    Ort
    Rhein Main (Darmstadt)
    Beiträge
    663
    Danke
    61
    Erhielt 112 Danke für 80 Beiträge

    Standard

    Weil Du ein Wort adressierst und 1 Wort weiter sind 2 Byte.

    Das ist aber nicht garantiert von der IEC Norm sondern frei von 3S so entschieden zu implementieren, weil es IHRER Logik entspricht.

    Die IEC Norm sagt ausdrücklich, dass sie Pointer Arithmetic NICHT unterstützt.

    Hierzu im Internet suchen:

    The 3rdEdition of IEC 61131-3 aus dem Jahr 2011
    Kommentiert von Eelco van der Wal
    Managing Director PLCopen


    Ich weiss dass es geht, heisst nicht, dass es Morgen auch noch geht.
    Im Software Slang spricht man von "well behaved programs" und warnt vor den anderen.
    Als Freelancer immer auf der Suche nach interessanten Projekten.

  9. #9
    Registriert seit
    07.06.2007
    Beiträge
    143
    Danke
    2
    Erhielt 24 Danke für 24 Beiträge

    Standard

    Du musst eigentlich nur das hier machen:
    G01.PNG

    Schreib einfach ADR(%IB6000) und ADR(%QB6000) an den Eingang dran und fertig.

    Intern kannst du dann folgendes machen:
    VAR_INPUT
    Adr_IN : POINTER TO BYTE;
    END_VAR

    VAR
    pTemp : POINTER TO BYTE;
    bByteArray : ARRAY [0..2] OF BYTE;
    END_VAR

    pTemp := Adr_In;
    bByteArray[0] := pTemp^;
    pTemp := pTemp + 1;
    bByteArray[1] := pTemp^;
    pTemp := pTemp + 1;
    bByteArray[2] := pTemp^;

    ==> Geht natürlich auch per Schleife. Anschließend kannst du auf die ersten 3 Bytes zugreifen. Am Ende deines FB oder PRG oder was auch immer musst du dann natürlich das Spielchen umgekehrt machen und auf die Outputs schreiben
    Also:
    Inbytes kopieren
    Programmcodeeinfügen
    Outbytes kopieren


    PS: Das machen viele Hersteller so, man übergibt die Adresse des ersten Bytes zum Beispiel für Servoantriebe und intern wird dann einfach die folgenden Bytes hochgezählt über Pointer um auf die anderen Daten zuzugreifen. Du musst dazu kein extra Array anlegen und das dann wieder übergeben. Geht auch ist aber nicht notwendig.
    Geändert von excelite (23.02.2016 um 16:50 Uhr)

  10. #10
    Booner ist offline Benutzer
    Themenstarter
    Registriert seit
    09.12.2011
    Beiträge
    52
    Danke
    2
    Erhielt 4 Danke für 4 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hei,

    jepp genau so habe ich es nun gemacht und es funktioniert zu meiner Zufriedenheit... ...fast.
    Wenn ich nur auf die Adresse zugreife, dann bekomme ich keine Werte. Erst wenn ich die Variable im Programm einmal aufrufe wird sie aktualisiert.
    Ich kann natürlich auch den Haken bei "Nicht verwendete I/O´s aktualisieren setzen. Hat das irgendwelche Nachteile?

    Genau wegen Deinem "PS" wollte ich es ja auch so machen. Die Idee ist nicht auf meinem Mist gewachsen.


    Grüße,

    Tom

Ähnliche Themen

  1. Step 7 Pointer (kein ANY) in SCL FC verwenden
    Von serverfreak95 im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 08.08.2015, 21:21
  2. Servoachse als FB verwenden
    Von SY50 im Forum CODESYS und IEC61131
    Antworten: 1
    Letzter Beitrag: 22.12.2014, 20:15
  3. Pointer als IN (FC/FB) wieder übergeben als Pointer
    Von saarlaender im Forum Simatic
    Antworten: 15
    Letzter Beitrag: 18.06.2012, 11:47
  4. Any-Pointer ohne SFC20 verwenden
    Von RONIN im Forum Simatic
    Antworten: 11
    Letzter Beitrag: 21.10.2009, 23:50
  5. array an Var_in ini AWL anbinden
    Von Gerri im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 21.09.2009, 09:47

Lesezeichen

Berechtigungen

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