Allen Bradley "MSG" Get Artibut Single / Set Atribut Single

Mcool

Level-2
Beiträge
37
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

Vorab:
  1. ich programmiere noch nicht lange Allen Bradley
  2. ich suche Hier im Forum Hilfe und nicht bei Allen Bradley da ich bei denen keinen Telefonsupport habe
Wichtig zu wissen:

Ich soll eine Ad On Instruction entwickeln, welche von einem Gerät azyklisch daten (Atribute) abholen und schreiben kann.
die Anzahl der Atribute ist festgelegt.
Dafür verwenden möchte ich "MSG" mit get atribut single und set atribut single. (wenn jemand etwas besseres kennt und es mir in Strukturiertem Text erklären kann, bin ich da offen)

Nun zu meinem Problem:

Wenn ich nun die Struktur für Die Funktion "MSG" anlege, so weiß ich nicht wie ich diese struktur genau befüllen soll.
vor allem macht mir der "Path" Probleme und der "Service Type" in welchem normal get oder set atribut single eingetragen wird.

da ich in der angelegten Preddefined Struktur diesen Service Type nicht finde, weiß ich nicht wo und wie ich den beim Strukturiertem Text eintragen soll.

Nun meine Bitte:

Verweist nur auf irgendwelche links, wenn sie frei verfügbar sind, und man sich nicht bei Allen Bradley anmelden muß.
Für Beispiele jedlicher art in Strukturiertem Text währe ich sehr dankbar.
und zu guter letzt,
nehmt mich nicht gleich auseinander, wenn ich etwas nicht so ausgedrückt habe wie es in der Allen Bradley sprache üblich ist. Ich lerne noch auf der Steuerung.
Fragt nach wenn ich etwas unklar formuliert habe, ich werde versuchen auf jede Frage die ihr mir stellt eine hoffentlich passende Antwort zu geben

wenn ich Bilder oder anderes hochladen soll, fragt nach ich tue mein bestes.

Grüße
Marco

P.S. ich dane euch schon mal im vorraus
 
Wenn ich nun die Struktur für Die Funktion "MSG" anlege, so weiß ich nicht wie ich diese struktur genau befüllen soll.
vor allem macht mir der "Path" Probleme und der "Service Type" in welchem normal get oder set atribut single eingetragen wird.

Ich weiß nicht, was für eine Struktur du da meinst. Und ich weiß nicht, wie flexibel du beim Path sein willst. Im Prinzip kannst du programmtechnisch auf alles zugreifen, was du beim Controltag (Monitor) siehst, also z.B. Class, Instance, Attribute. Was aber nicht geht (zumindest mein Stand) ist z.B. der ServiceType. Den musst du von Hand definieren, wenn du verschiedene in der AOI brauchst, brauchst du mehrere MSG. Die MSG musst du ja an die AOI als InOut übergeben, die Daten, welche gelesen oder verschickt werden sollen, musst du ebenfalls "nach außen" geben, um sie da im MSG zu konfigurieren.
Path in der Konfigurationsoberfläche:


Path.png
Was beim Pfad aber verwirrend ist: wenn man beispielsweise in der Oberfläche des MSG folgendes eingibt:

1, 1, 2, 192.168.1.10, 1, 0

dann steht im String:

'$01$01$12$p192.168.1.10$01$00'

aus der "2" für Backplane wird eine 12, das "$p", dezimal 12 steht für die Anzahl der folgenden Zeichen, das "$0" am Ende ist ein Füllzeichen, der Pfad(bzw. die IP-Adresse?) muss immer eine gerade Anzahl an Bytes haben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also grundsätzlich die erste Anlaufstelle wäre die Literature Library von Rockwell, die ist frei zugänglich auch ohne Supportvertrag.
Das Logix Referenzhandbuch geht sehr detailiert auf alle Funktionen ein 1756-RM003X-EN-P
Zu deinem spezifischen Problem kann ich dir aber nicht weiterhelfen.
 
Hallo Leute,

zuerst einmal vielen Dank für die schnellen Antworten!

@Schmidi: danke für den Link. habe ich mir angeschaut und dann auch gemerkt, dass ich das selbe Dokument in Deutscher Übersetzung schon habe.

@Oberchefe: ich hab mal 3 Bilder angehängt um die Struktur "Message" welche verwendet wird darzustellen. Dein "Example 4" welches du angehängt hast erklärt auch einiges was den Path angeht. Werde ich probieren. wenn du vieleicht das Orginal Dokument oder einen Link darauf hättest währe das super.
Am geschicktesten für mich währe natürlich, wenn man den Service Type (Siehe Bild 3) von einem Patameter aus beschreiben könnte.
(Insgeheim befürchte ich aber das diese möglichkeit nicht geboten wird)
Sollte jemand wissen wie dies funktioniert, bitte hier reinschreiben.

Ich habe mir auch schon überlegt, ob man die ganzen einstellungen auch ohne eine MSG Box machen kann, denn meine Kollegen Robieprogrammierer machen das mit ihren Plugins.

nun denn Ihr Recken!
Danke schon mal für all eure Hilfe
und bitte weitere Tipps schreiben, egal wie unwichtig sie erscheinen, vielleicht hilfts weiter.

in diesem Sinne
Haut rein
Marco
 

Anhänge

  • 1.JPG
    1.JPG
    118,4 KB · Aufrufe: 13
  • 2.JPG
    2.JPG
    9 KB · Aufrufe: 13
  • 3.JPG
    3.JPG
    42,6 KB · Aufrufe: 14
Werde ich probieren. wenn du vieleicht das Orginal Dokument oder einen Link darauf hättest währe das super.

Musst nur in der Software "F1" drücken, da mal nach "path" suchen. Ansonsten im Handbuch Seite 146:

ServiceType geht (zumindest in meiner Version) noch nicht, in deinem Screenshot gibt's die Variable auch nicht, geht demzufolge in deiner Version (welche auch immer das ist) auch nicht.

Ich habe mir auch schon überlegt, ob man die ganzen einstellungen auch ohne eine MSG Box machen kann, denn meine Kollegen Robieprogrammierer machen das mit ihren Plugins.

Wie oben geschrieben geht Class, Instance, Attribute. Wenn du also verschiedene davon brauchst aber den gleichen ServiceType, dann kannst du das mit einer MSG nacheinander machen.

Also erst zuweisen, Beispiel:
Daten_Holen.Path := '$01$02$12$0B192.168.1.2$00'; //Pfad definieren
Daten_Holen.Class := 16#C7; //Class definieren
Daten_Holen.Instance := 4; //Instance definieren
Daten_Holen.Attribute :=16#1; //Attribute definieren
Daten_Holen.Req_Len := 50; //ReqestLen definieren

Dann den Msg aufrufen (Wichtig: nur einmal, nicht zyklisch):
MSG(Daten_Holen);

Wenn fertig Daten wegkopieren:
IF Daten_Holen.DN Then
COP(DatRec,DatX,1);

Dann kann es mit dem nächsten weiter gehen.


Mit welchem Gerät willst du überhaupt kommunizieren?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Oberchefe,

das mit dem einstellen des Service Typs hab ich mir auch schon überlegt.
Wenn ich ein Projekt machen würde, welches beim Kunde laufen müste würde ich das vermutlich genau so schreiben.
Leider muß ich eine add-in instruction schreiben, welche siech die Kunden dann zu m Produkt runterladen könne, um ihnen dann die müßige Programmierarbeit zu erleichtern.

und das ist eben das Problem, dass man in einer Add-on Instruction den service typ nicht einstellen kann 😭

ich finde das zimlich schade, aber so isses halt.

Gruß Marco
@Oberchefe : hast ne PM
 
Leider muß ich eine add-in instruction schreiben, welche siech die Kunden dann zu m Produkt runterladen könne, um ihnen dann die müßige Programmierarbeit zu erleichtern.

und das ist eben das Problem, dass man in einer Add-on Instruction den service typ nicht einstellen kann

In diesem Fall würde ich die AOI in einer Testumgebung in einem KOP-Netzwerk aufrufen, dort dann fertig konfigurieren und danach den Rung exportieren. Dann kann ihn der Kunde in seinem Projekt importieren und hat den (bzw. die) MSG fertig konfiguriert. Schwieriger wird es aber mit dem Pfad, dein Gerät kann bei einer CLX ja direkt am Enet-Port der CPU hängen, er kann aber auch über die Backplane und eine CNB-Karte dran hängen (oder oder oder...).

Ich sehe es aber als kein großes Problem an, dem Kunden eine kleine Doku mitzuliefern in dem mit zwei Screenshots die einzustellenden Dinge kurz erklärt sind. Brauchst du ja für die Hardwarekonfiguration auch.
 
Hallo Leute,

leider Quäle ich mich immer noch mit der "msg" Box in den Add- in instructions. Leider gibt es keine vernünftige beschreibung der inhalte der msg Struktur. ich suche noch beschreibungen wie man diese inhalte von ausen füllen kann. in den beschreibungen welche ich gefunden habe wird immen nur beschrieben, dass man etwas eintragen muß, aber es sind nie konkrete beispiele dabei.
Vielleicht hat jemand einebessere Beschreibung.

so wie in dem Bild zu sehen.
 

Anhänge

  • 4.JPG
    4.JPG
    155,5 KB · Aufrufe: 3
Hallo Oberchefe,
ich Danke Dir erst mal, dass du mir immer gleich antwortest.

Es ist bekannt, was in die MSG Box an verschiedenen Stellen eingetragen werden muß. (Siehe beigefügte Beispielbilder)
was hier auffallen müste, das im Destination Element nichts eingetragen ist. Was ich durch Testen herausgefunden habe, dass hier nur eine Var eingetragen werden kann, wenn die Varriable eine Controll Varriable ist.
Auch ist mir nicht klar, wozu manche Parameter in der MSG Box sind und wie man sie genau mit ST implementierung anspricht und was man genau eintragen muß. Als Beispiel habe ich ja im Kommentar vorher ein Bild gepostet.
 

Anhänge

  • 6.JPG
    6.JPG
    45,6 KB · Aufrufe: 4
  • 5.JPG
    5.JPG
    42,9 KB · Aufrufe: 4
Jetzt mal eine kleine Anleitung und ein Beispiel Code:

Ich persönlich verzichte immer gerne auf die Installation der EDS weil ich dann bei der Weitergabe des Projekts an Kunden denen nicht erklären muss, welche EDS sie zu installieren haben und benutze lieber das "Generic Ethernet Module":

GenEthernetModule.png

Die Schnittstelle des AOI würde dann ungefähr so aussehen:

Parameter.png

Hier benötigt man in diesem Fall zwei "MESSAGE" und dazu für jede den Datenbereich zum Senden/Empfangen (msgDataSet/msgDataGet), Datentyp SINT Array mit der maximal verwendeten Größe, hier also beim Senden die 24 Bytes für die 6 Float (TCP...) und beim Empfagen 214 Byte für das Array Of Char.

Bei "In" und "Out" sollen dann die zyklischen Daten vom Greifer verschaltet werden, die beiden Datentypen werden von der Software automatisch angelegt, sobald das "Generic Ethernet Device" angelegt ist.

DataExchange ist ein UDT mit den azyklisch zu lesenden/schreibenden Daten.

Der Aufruf des AOI sieht dann so aus:

AufrufAoi.png

Der Kunde muss dann noch die beiden MSG konfigurieren indem er die beiden Knöpfe neben den Tagnamen (msgGet/msgSet) betätigt:



ConfigSetMsg.png
Ausgewählt wird beim Set erst mal der Message Type CIP Generic, Service Type Set Attribute Single, Class A2, Instance 0 und Attribute 5. Die letzten 3 werden aber später auch im AOI passend beschrieben.
Beim Source Element wird der Tag beschalten, der zum Datenaustausch von/zum AOI dient, Source Length kann erst mal mir 1 beschalten werde, wird aber später auch vom AOI aus variiert.

Im Reiter "Communication" wird auf das angelegte Generic Ethernet Modul verwiesen:

ConfigPath.png

Konfiguration des Get:

ConfigGetMsg.png

Im Prinzip ähnlich, Service Type aber Get Attribute Single, Source Element bleibt leer dafür das Destination Element mit dem Tag beschrieben, über das die gelesenen Daten dann in das AOI wandern.

Pfad gleich wie beim Set.

Die beiden Datenbereiche (Tags SetMsgData/GetMsgData) müssen aktuell Controller Tags sein (zumindest offiziell), die beiden MESSAGE Tags funktionieren in aktuellen Versionen auch als Local Tags, in früheren Versionen waren da aber auch zwingend Controller Tags erforderlich.

Im Anhang dann noch der Export der Hardware und der Rungs. Beim Importieren erst die Hardware importieren, dann den Rung in einer KOP Routine.






Ach ja: im Handbuch steht bei ein paar Parametern (z.B.tool_cent_point, cent_of_mass, enable_softreset) Zugriffsrecht Lesen, das muss (zumindest dem Text nach) Lesen und Schreiben sein?
 

Anhänge

  • ConfigSetMsg.png
    ConfigSetMsg.png
    23,4 KB · Aufrufe: 1
  • ConfigSetMsg.png
    ConfigSetMsg.png
    23,4 KB · Aufrufe: 1
  • Parameter.png
    Parameter.png
    28,1 KB · Aufrufe: 1
  • AOIneu.zip
    8,9 KB · Aufrufe: 0
Zuletzt bearbeitet:
Wichtig: Code ist nicht getestet


PHP:
#Region Acycl
//Überwachung Timeout
tonTimeOut.PRE := 5000;
tonTimeOut.TimerEnable := diStep=diOldStep;
TONR(tonTimeOut);

diOldStep := diStep;


case diStep of
    0:    //Starten
        diStep := diStep + 1;
    
    1:
        msgGetAttributeSingle.Class := 16#A2;
        msgGetAttributeSingle.Instance := 16#118;    //Fehlercode lesen anstossen
        msgGetAttributeSingle.Attribute := 16#5;
        msgGetAttributeSingle.REQ_LEN := 0;
        MSG(msgGetAttributeSingle);
        diStep := diStep + 1;
        bNoErrExe := 1;
        
    2:
        if msgGetAttributeSingle.DN OR msgGetAttributeSingle.ER then
            if msgGetAttributeSingle.DN then    //Fehlercode lesen erfolgreich
                COP(msgDataGet[0],DataExchange.err_code,1);
            else
                bNoErrExe := 0;
            end_if;
        msgGetAttributeSingle.Class := 16#A2;
        msgGetAttributeSingle.Instance := 16#120;    //Warncode lesen anstossen
        msgGetAttributeSingle.Attribute := 16#5;
        msgGetAttributeSingle.REQ_LEN := 0;
        MSG(msgGetAttributeSingle);
            diStep := diStep + 1;
        end_if;
        
    3:
        if msgGetAttributeSingle.DN OR msgGetAttributeSingle.ER then
            if msgGetAttributeSingle.DN then    //Warncode lesen erfolgreich
                COP(msgDataGet[0],DataExchange.wrn_code,1);
            else
                bNoErrExe := 0;
            end_if;
            msgSetAttributeSingle.Class := 16#A2;
            msgSetAttributeSingle.Instance := 16#128;    //Diagnoseindex schreiben
            msgSetAttributeSingle.Attribute := 16#5;
            COP(sys_msg_req,msgDataSet[0],2);
            msgSetAttributeSingle.REQ_LEN := 2;
            MSG(msgSetAttributeSingle);
            diStep := diStep + 1;
        end_if;

    4:
        if msgSetAttributeSingle.DN OR msgSetAttributeSingle.ER then
            if msgSetAttributeSingle.DN then    //Diagnoseindex schreiben erfolgreich
            diStep := diStep + 1;
            else
            diStep := diStep + 2;
                bNoErrExe := 0;
            end_if;
            msgGetAttributeSingle.Class := 16#A2;
            msgGetAttributeSingle.Instance := 16#130;    //Diagnosemessage lesen
            msgGetAttributeSingle.Attribute := 16#5;
            msgGetAttributeSingle.REQ_LEN := 0;
            MSG(msgGetAttributeSingle);

        end_if;
        
    5:
        if msgGetAttributeSingle.DN OR msgGetAttributeSingle.ER then
            if msgGetAttributeSingle.DN then    //Diagnosemessage lesen erfolgreich
                COP(msgDataGet[0],DataExchange.sys_msg_buffer[sys_msg_req].DATA[0],214);
                DataExchange.sys_msg_buffer[sys_msg_req].LEN := 214;
                sys_msg_req := sys_msg_req + 1;
                IF sys_msg_req > 31 then
                    sys_msg_req := 0;
                end_if;
            else
                bNoErrExe := 0;
            end_if;
            msgGetAttributeSingle.Class := 16#A2;
            msgGetAttributeSingle.Instance := 16#238;    //Istgeschwindigkeit lesen
            msgGetAttributeSingle.Attribute := 16#5;
            msgGetAttributeSingle.REQ_LEN := 0;
            MSG(msgGetAttributeSingle);
            diStep := diStep + 1;
        end_if;
    6:
        if msgGetAttributeSingle.DN OR msgGetAttributeSingle.ER then
            if msgGetAttributeSingle.DN then    //Istgeschwindigkeit lesen erfolgreich
                COP(msgDataGet[0],DataExchange.actual_vel,1);
            else
                bNoErrExe := 0;
            end_if;
            msgGetAttributeSingle.Class := 16#A2;
            msgGetAttributeSingle.Instance := 16#380;    //Zeitspanne Nachgreifen lesen
            msgGetAttributeSingle.Attribute := 16#5;
            msgGetAttributeSingle.REQ_LEN := 0;
            MSG(msgGetAttributeSingle);
            diStep := diStep + 1;
        end_if;
    7:
        if msgGetAttributeSingle.DN OR msgGetAttributeSingle.ER then
            if msgGetAttributeSingle.DN then    //Zeitspanne Nachgreifen lesen erfolgreich
                COP(msgDataGet[0],grp_prehold_time,1);
                if DataExchange.grp_prehold_time <> grp_prehold_time then
                    diStep := diStep + 1;    //Wert muss geändert werden
                else
                    diStep := diStep + 3;    //Wert muss nicht geändert werden
                end_if;
            else
                bNoErrExe := 0;
                diStep := diStep + 3;
            end_if;
        end_if;
    8:
        msgSetAttributeSingle.Class := 16#A2;
        msgSetAttributeSingle.Instance := 16#380;    //Zeitspanne Nachgreifen schreiben
        msgSetAttributeSingle.Attribute := 16#5;
        COP(DataExchange.grp_prehold_time,msgDataSet[0],2);
        msgSetAttributeSingle.REQ_LEN := 2;
        MSG(msgSetAttributeSingle);
        diStep := diStep + 1;
    9:
        if msgSetAttributeSingle.DN OR msgSetAttributeSingle.ER then
            if msgSetAttributeSingle.DN then    //Zeitspanne Nachgreifen schreiben erfolgreich
                ;
            else
                bNoErrExe := 0;
            end_if;
            diStep := diStep + 1;
        end_if;
    10:
            msgGetAttributeSingle.Class := 16#A2;
            msgGetAttributeSingle.Instance := 16#3B0;    //TCP lesen
            msgGetAttributeSingle.Attribute := 16#5;
            msgGetAttributeSingle.REQ_LEN := 0;
            MSG(msgGetAttributeSingle);
            diStep := diStep + 1;
    11:
        if msgGetAttributeSingle.DN OR msgGetAttributeSingle.ER then
            if msgGetAttributeSingle.DN then    //TCP lesen erfolgreich
                COP(msgDataGet[0],tool_cent_point,1);
                if DataExchange.tool_cent_point.x <> tool_cent_point.x OR
                    DataExchange.tool_cent_point.y <> tool_cent_point.y OR
                    DataExchange.tool_cent_point.z <> tool_cent_point.z OR
                    DataExchange.tool_cent_point.a <> tool_cent_point.a OR
                    DataExchange.tool_cent_point.b <> tool_cent_point.b OR
                    DataExchange.tool_cent_point.c <> tool_cent_point.c then
                    diStep := diStep + 1;    //Wert muss geändert werden
                else
                    diStep := diStep + 3;    //Wert muss nicht geändert werden
                end_if;
            else
                bNoErrExe := 0;
                diStep := diStep + 3;
            end_if;
        end_if;
    12:
        msgSetAttributeSingle.Class := 16#A2;
        msgSetAttributeSingle.Instance := 16#3B0;    //TCP schreiben
        msgSetAttributeSingle.Attribute := 16#5;
        COP(DataExchange.tool_cent_point,msgDataSet[0],24);
        msgSetAttributeSingle.REQ_LEN := 24;
        MSG(msgSetAttributeSingle);
        diStep := diStep + 1;   
    13:
        if msgSetAttributeSingle.DN OR msgSetAttributeSingle.ER then
            if msgSetAttributeSingle.DN then    //TCP schreiben erfolgreich
                ;
            else
                bNoErrExe := 0;
            end_if;
            diStep := diStep + 1;
        end_if;
    14:    //letzter Schritt
        
        diStep := 0;
        
    end_case;
        
        //Fehler?
        commFault := NOT bNoErrExe OR tonTimeOut.DN;

        if tonTimeOut.DN then
            diStep := 0;
        end_if;
        
        //Fehlercode Get ausgeben
        if msgGetAttributeSingle.ER then
            ErrCodeGet := msgGetAttributeSingle.ERR;
            ExtErrCodeGet := msgGetAttributeSingle.EXERR;
        end_if;
        
        //Fehlercode Set ausgeben
        if msgSetAttributeSingle.ER then
            ErrCodeSet := msgSetAttributeSingle.ERR;
            ExtErrCodeSet := msgSetAttributeSingle.EXERR;
        end_if;
            
#EndRegion

#Region Cycl


Cps(In,GripIn,1);

//Hier kommt die Ansteuerung der zyklischen Signale

    GripOut.CommandSpeed := CommandSpeed * 2147483647 / 100;
    GripOut.CommandPos := CommandPos;


    if GripIn.ReadyForOperation then
        ;    //was auch immer passieren sol
    end_if;

    if 1=2 then
        GripOut.ReleaseWorkpiece := 1;
    end_if;

    ActPos := GripIn.ActPos;


Cps(GripOut,Out,4);
#EndRegion
 
Add-On Instructions have one primary logic routine that defines the behavior
of the instruction when executed. This logic routine is like any other routine
in the project and has no additional restrictions in length. The total number of
Input parameters plus Output parameters plus local tags can be up to 512.
Logix Designer versions 27 and earlier do not set a limit on the number of
InOut parameters. However, limit extended properties (.@Min and .@Max
syntax) should not be defined on an InOut parameter of an Add-On
Instruction and should not be used in Add-On Instruction definition logic or
the logic does not verify.
Logix Designer version 28 limits the number of InOut parameters for Add-On
Instructions to 40.
Logix Designer versions 29 and later limit the number of InOut parameters
for Add-On Instructions to 64 and limit the Add-On Instruction nesting levels
to 16. Rockwell recommends limiting the level of nesting to eight levels to
reduce complexity and make the instruction easier to manage.
Limits cannot be accessed inside Add-On Instruction logic.
The maximum data instance supported (which includes Inputs, Outputs, and
local tags) is two megabytes. The data type size is displayed on the bottom of
the Parameters and Local Tags tab in the Add-On Instruction Definition.

 
Zurück
Oben