INTERRUPT Programmierung für Anfänger

  • Ein Hallo in die Runde,


    ich versuche mich mit der Interrupt-Programmierung:


    Cell Programm:
    DEF CELL ( )
    EXT P_01_Schweissen()
    EXT P_02_Heimfahrt()


    INTERRUPT DECL 81 WHEN $IN[1]== TRUE DO P_04_Heimfahrt()
    INTERRUPT ON 81
    WAIT sec 0.012


    LOOP
    P00 (#EXT_PGNO,#PGNO_GET,DMY[],0 )
    SWITCH PGNO ; Select with Programnumber


    CASE 1
    P00 (#EXT_PGNO,#PGNO_ACKN,DMY[],0 ) ; Reset Progr.No.-Request
    P_01_Schweissen(); Call User-Program


    CASE 2
    P00 (#EXT_PGNO,#PGNO_ACKN,DMY[],0 ) ; Reset Progr.No.-Request
    P_02_Heimfahrt(); Call User-Program

    DEFAULT
    P00 (#EXT_PGNO,#PGNO_FAULT,DMY[],0 )

    ENDSWITCH
    ENDLOOP

    INTERRUPT OFF 81
    WAIT sec 0.012



    P_02_Heimfahrt:
    ;FOLD USER INI
    INTERRUPT OFF 81
    WAIT sec 0.012
    ;ENDFOLD
    ;
    ;sehr viel Programmcode
    ;
    INTERRUPT ON 81
    WAIT sec 0.012



    P_01_Schweissen:
    BREAK???
    RESUME???
    HALT???



    Betriebsart: Automatik Extern, Cell ist angewählt
    Das Programm "P_01_Schweissen" soll wenn Eingang 1 durch die übergeordnete SPS gesetzt wird, abgebrochen werden.
    Falls der Roboter in Bewegung ist, soll eine bahntreue Bremsung ausgeführt werden.
    Das Programm "P_02_Heimfahrt" wird aufgerufen und ausgeführt.


    Meine Probleme liegen jetzt in der Modifikation des Programms "P_01_Schweissen".
    Auch glaube ich, das die Deklaration des Interruptes "unglücklich" platziert ist.
    Muss die Abfrage ob Eingang 1 TRUE ist nicht ins die SUB.SPS?


    Auch das Benutzen der Suchfunktion und das Lesen der KUKA Dokumentation brachte keinen nennenswerten Wissenszuwachs.
    Vielleicht schafft Ihr es ja :zwink:

  • Schritt für Schritt zum Roboterprofi!
  • DEF CELL ( )
    EXT P_01_Schweissen()
    EXT P_02_Heimfahrt()


    INTERRUPT DECL 81 WHEN $IN[1]== TRUE DO abbruchSchweissen()
    INTERRUPT ON 81
    WAIT sec 0.012


    LOOP
    P00 (#EXT_PGNO,#PGNO_GET,DMY[],0 )
    SWITCH PGNO ; Select with Programnumber


    CASE 1
    P00 (#EXT_PGNO,#PGNO_ACKN,DMY[],0 ) ; Reset Progr.No.-Request
    P_01_Schweissen(); Call User-Program


    CASE 2
    P00 (#EXT_PGNO,#PGNO_ACKN,DMY[],0 ) ; Reset Progr.No.-Request
    P_02_Heimfahrt(); Call User-Program



    ENDSWITCH


    if ($IN[1]) then
    ; achtung kollisionsgefahr
    P_02_Heimfahrt()
    endif
    ENDLOOP

    INTERRUPT OFF 81
    WAIT sec 0.012



    def abbruchSchweissen()
    brake
    resume
    end

  • INTERRUPT DECL 81 WHEN $IN[1]== TRUE DO abbruchSchweissen()
    INTERRUPT ON 81
    WAIT sec 0.012



    Der interrupt on ist an Der stelle falsche. Wenn der interrupt im hauptprogramm aktiv wird kommt es zum Fehler.
    Interrupt on hier immer im unterprogramm oder unmittelbar vor dessen Aufruf.
    Wozu das wait gut sein soll,weiß ich nicht.


    def abbruchSchweissen()
    brake
    resume
    end
    For dem brake,bitte den interrupt ausschalten.

    Einmal editiert, zuletzt von soma ()

  • soma hat Recht. Sonst gibt's "ungültige Programmstruktur für Resume".


    Und vor dem Einschallten des Interrupts immer schön abfragen, ob die Bedingung, die den Interrupt einschaltet nicht aktiv ist. Sonst kann's auch da zu Probs führen.


    WAIT FOR NOT $IN[1]
    INTERRUPT ON 81

    Greetings, Irrer Polterer!

    Wie poste ich falsch? Nachdem ich die Suche und die FAQ erfolgreich ignoriert habe, erstelle ich das gleiche Thema in mehreren Unterforen, benutze einen sehr kreativen Titel wie "Hilfe", am Besten noch mit mehreren Ausrufezeichen, und veröffentliche einen so eindeutigen Text, dass sich jeder etwas Anderes darunter vorstellt.


    Life is a beta version. Full of bugs and no Manual.

  • Dankeschön für die Tipps.


    ich fasse meinen Wissenszuwachs zusammen:


    Im Cell-Programm nach der Ini-Falte und vor der Loop - Endloop Schleife:
    INTERRUPT DECL 81 WHEN $IN[1]== TRUE DO abbruchSchweissen()


    Im Cell Programm nach der Loop - Endloop Schleife:
    INTERRUPT OFF 81
    WAIT sec 0.012


    Im Unterprogramm (bei mir P_01_Schweissen) nach der Ini-Falte:
    WAIT FOR NOT $IN[1] oder WAIT FOR $IN[1] == FALSE
    INTERRUPT ON 81
    WAIT sec 0.012


    Im Unterprogramm (bei mir P_01_Schweissen) direkt vor dem END
    INTERRUPT OFF 81
    WAIT sec 0.012


    das zusätzliche Unterprogramm abbruchSchweissen()
    def abbruchSchweissen()
    INTERRUPT OFF 81
    WAIT sec 0.012
    brake
    resume
    end


    soma: das Wait 0.012 bewirkt ein Vorlaufstop und eine Wartezeit von 0,012Sekunden. Genau so lange soll der Interpolationstakt meiner KR C4 sein; also genau die Zeit, die der Rechenknecht im Vierkantkasten braucht um einmal durch mein erstelltes Programm zu rasen. Das Wait 0.012 stellt sicher, dass beim darauf folgenden Befehl der Interrupt sicher aktiviert oder deaktiviert ist.


    *ich konnt auch mal mit Randgruppenwissen glänzen :grinser043:*


  • soma hat Recht. Sonst gibt's "ungültige Programmstruktur für Resume".


    Und vor dem Einschallten des Interrupts immer schön abfragen, ob die Bedingung, die den Interrupt einschaltet nicht aktiv ist. Sonst kann's auch da zu Probs führen.


    WAIT FOR NOT $IN[1]
    INTERRUPT ON 81


    Nicht direkt zu Problemen. Man muss nur wissen, dass die Interrupter Flankengesteuert ausgewertet werden.
    Frag man zB den Eingang 1 auf HIGH ab, und beim aktivieren ist dieser HIGH, wird der Interrupter nicht ausgelöst, da keine Flanke entstehen kann.
    Also das Programm schon so vorbereiten, dass dieser Fall nicht vorkommen kann.
    Ein Wait kann unter umständen ja andere Probleme verursachen. Ich finde aber, dass die Interrupter recht schön beim KUKA Funktionieren. Bisher hatte ich da nicht grössere Probleme.

  • Ich persönlich sehe keinen Sinn in Wait sec 0.012.


    Hatte noch nie Probleme,dass der Programmzeiger diese Wartezeit benötigt.
    Vorlaufstopp mach ich mit Wait sec 0.0 oder $Advance.


    Kann mich jemand eines besserern belehren?


  • Kann mich jemand eines besserern belehren?


    Nö! Sehe jch auch keinen Sinn drin...

    Greetings, Irrer Polterer!

    Wie poste ich falsch? Nachdem ich die Suche und die FAQ erfolgreich ignoriert habe, erstelle ich das gleiche Thema in mehreren Unterforen, benutze einen sehr kreativen Titel wie "Hilfe", am Besten noch mit mehreren Ausrufezeichen, und veröffentliche einen so eindeutigen Text, dass sich jeder etwas Anderes darunter vorstellt.


    Life is a beta version. Full of bugs and no Manual.


  • Nö! Sehe jch auch keinen Sinn drin...


    Dito, die ganze Sache sollte schon mal rein gar nichts mit dem Interpolationstakt zu tun haben. Der ist für andere Dinge zuständig.
    Das "Wait sec" in der Interrupt-Service-Routine vor dem "Brake" ist m.E. schädlich, da sich der Roboter in der Zeit noch weiterbewegen kann. Wenn schon ein Wait, dann hinter dem Brake.

    Einmal editiert, zuletzt von Hermann ()

  • Auszüge aus KRC4 Systemintegrator Doku:


    Einschalten des Interrupts
    Der Zustandswechsel
    darf frühestens einen Interpolationstakt nach INTERRUPT ON erfolgen.
    (Dies kann erreicht werden, indem man nach INTERRUPT ON ein WAIT
    SEC 0.012 programmiert. Wenn kein Vorlaufstopp gewünscht ist, kann zusätzlich
    vor dem WAIT SEC ein CONTINUE programmiert werden.)
    Der Grund ist, dass INTERRUPT ON einen Interpolationstakt (= 12 ms)
    benötigt, bis der Interrupt tatsächlich aktiviert ist. Wenn der Zustand zuvor
    wechselt, kann der Interrupt den Wechsel nicht erkennen.

    Daher kommen die 12ms


    RESUME bricht alle laufenden Interrupt-Programme und alle
    laufenden Unterprogramme ab bis zu der Ebene, in der der aktuelle Interrupt
    deklariert wurde.
    Zum Zeitpunkt der RESUME-Anweisung darf der Vorlaufzeiger nicht in der
    Ebene sein, in der der Interrupt deklariert wurde, sondern er muss sich mindestens
    eine Ebene tiefer befinden.


    Bedeutet wenn der Interrupt in der gleichen Ebene aktiv ist wie die Deklaration weiß die Steuerung mit dem RESUME-Befehl nicht mehr in welche Ebene sie zurück soll weil sie ja schon dort ist. Und das erzeugt dann einen STOP-Fehler.


  • soma: das Wait 0.012 bewirkt ein Vorlaufstop und eine Wartezeit von 0,012Sekunden. Genau so lange soll der Interpolationstakt meiner KR C4 sein; also genau die Zeit, die der Rechenknecht im Vierkantkasten braucht um einmal durch mein erstelltes Programm zu rasen. Das Wait 0.012 stellt sicher, dass beim darauf folgenden Befehl der Interrupt sicher aktiviert oder deaktiviert ist.


    Nur der Vollständigkeit halber sei angemerkt, dass der Interpolationstakt die Zeit für die Abarbeitung eines Befehls ist.
    Das Roboterprogramm wird sequentiell abgearbeitet, der aktuelle Befehl wird durch den Satzzeiger angezeigt, einen permanenten Durchlauf wie in einer SPS gibt es hier nicht.

    Somit ist der Interpolationstakt auch nicht mit der Zykluszeit einer SPS gleichzusetzen.
    (Mal abgesehen von der sps.sub. Dort könnte man durch von Anzahl der Befehle * Interpolationstakt = "Zykluszeit" sprechen.)

    never touch a running system

  • hmmmm

    Zitat

    Befehle * Interpolationstakt = "Zykluszeit"


    hmmm
    bei 12ms und 100 Befehle -> 1 sec. ...
    kann nicht sein .....


    Eher:
    Interpolationstakt in dem alle "Prozesse" aufgerufen werden
    Ich meine, in der Zeit schaft er 3000 Befehle


    INTERRUPT läuft im "Hintergrund"
    da kann es gut sein, dass er erst in nächsten "Zyklus" aktiv wird und die Bedingungen abgearbeitet werden

  • Somit ist der Interpolationstakt auch nicht mit der Zykluszeit einer SPS gleichzusetzen.
    (Mal abgesehen von der sps.sub. Dort könnte man durch von Anzahl der Befehle * Interpolationstakt = "Zykluszeit" sprechen.)


    Neenee, keinesfalls.
    Man kann sich mit entsprechenden Timer-Befehlen ja die Ausführungszeit (einen Zyklus) der SPS.SUB in eine Variable schreiben lassen und überwachen. Wenn das Programm im Submit-Interpreter sehr groß ist, dann kriegt man da auch schon mal 24ms oder 36 usw. angezeigt.
    Wenn der Robbi so schnarchlangsam wäre, dann hätte ich auf Gärtner umgeschult, denn da wachsen ja die Radieschen schneller.


    Grüße,
    Michael


  • Na? Du bist Dir da 100% sicher?
    Wie lang ist denn Dein sps.sub? Timer Befehle sind ausserdem asynchron, inwieweit die Zeitmessung für eine "Zykluszeiterfassung" zu gebrauchen ist, halte für fragwürdig. Weiterhin ist die Abarbeitungsgeschwindigkeit in sps.sub abhängig vom Durchlauf. Also durch ein "if" kann schon die Anzahl der bearbeiteten Befehle variieren.


    Nebenher: Mein Kenntnisstand ist, dass die KRC4 4ms Interpolationstakt hat. Kann das hier jemand bestätigen? Dann würde der Wartetakt auf den Interrupt ja 3 Interpolationstakte lang sein. Gab es für die KRC2 eine ähnliche Vorgabe?



    Grüße

    never touch a running system


  • Na? Du bist Dir da 100% sicher?
    Wie lang ist denn Dein sps.sub?


    Yes, Sir.
    Ich hab hier eine auf einer KRC 2, zusätzlich zur originalen SPS.SUB (die ja auch noch mal in die Gripper-Tech-Sache verzweigt) noch eine Datei mit 20 KB Anweisungen (607 Zeilen ohne Leerzeilen, danke UE), die zeigt die besagten 24.
    Eine andere auf einer KRC 4 hat 31 KB Anweisungen (939 Zeilen mit Befehlen), die zeigt auch schon mal 48ms, je nachdem, wo reinverzweigt wird. Die Zahl der Zeilen sagt allerdings wenig, da ja öfters Loops durchlaufen werden, teilweise ineinandergeschachtelt, und andere Bereiche nicht aufgerufen werden.


    Allgemein ist das bei meinen Maschinchen immer so ein Thema, deswegen bin ich ein wenig sensibilisiert dafür. Bei einigen Programmen passiert es tatsächlich, dass der Robbi mal eine halbe Sekunde Bedenkzeit braucht, was natürlich sofort auffällt, wenn er sich nicht bewegt, und zu Fragerei und albernen Verbesserungsvorschlägen seitens der Projektleiter führt. Aber dazu muss schon ein extremer Logikblock durchlaufen werden.
    Hatte neulich noch auf einer KRC2 eine Messwerterfassung nachgerüstet, ca. 450 (Integer)Werte mit Glättung über Median, Fensterwertsuche, diversen Vergleichen usw., und es gab keine sichtbare Verzögerung im Programm. Von daher....


    Aber das ist hier schon ziemlich Off Topic.


    Grüße,
    Michael

  • So da bin ich wieder.


    Inzwischen sind wir mit unseren 2 Agilanten umgezogen und fahren beim Kunden Versuche. UNd wie sollte es sein: das Ding mit dem Interrupt verfolgt mich.
    Wie ausführlich besprochen habe ich nachfolgende Modifikationen am Programm vorgenommen:


    Im Cell-Programm nach der Ini-Falte und vor der Loop - Endloop Schleife:
    INTERRUPT DECL 81 WHEN $IN[242]== TRUE DO Abbruch()


    Im Cell-Programm in Loop - Endloop Schleife:
    SWITCH PGNO
    CASE 1
    P_01_Brenner_komplett()
    .
    .
    CASE 6
    P_06_Heimfahrt()


    Im Cell Programm nach dem Endloop Befehl und vor dem END:
    INTERRUPT OFF 81
    WAIT sec 0.012


    Im Unterprogramm (bei mir P_01_Brenner_komplett( )) nach der Ini-Falte:
    WAIT FOR $IN[242] == FALSE
    INTERRUPT ON 81
    WAIT sec 0.012

    Im Unterprogramm (bei mir P_01_Brenner_komplett( )) direkt vor dem END
    INTERRUPT OFF 81
    WAIT sec 0.012


    Im Unterprogramm (bei mir P_06_Heimfahrt()) nach der INI-Falte
    INTERRUPT OFF 81
    WAIT sec 0.012


    das zusätzliche Unterprogramm (bei mir Abbruch ( ))
    DEF Abbruch ( )
    FOLD INI


    INTERRUPT OFF 81
    WAIT sec 0.012
    brake
    resume

    END


    Automatik Extern läuft durch die übergeordnete SPS gestartet, Programm P_01_Brenner_komplett wird ausgewählt und abgearbeitet.
    Nun schickt sie SPS einen Impuls auf Eingang 242 und das Programm P_01 sollte abbrechen und unser oranger Freund sollte nach Hause fahren. Macht er aber nicht. Er bleibt im Programm P_01 hängen und es erscheint die Meldung: Anweisung unzulässig.


    Vielleicht habe ich ja das Abbruch Programm Falsch positioniert:


    KRC
    R1
    MADA
    PROGRAMM
    TEILPROGRAMME
    abbruch.src
    p_01_Brenner_komplett.src
    p_06_heimfahrt.src
    SYSTEM
    TP
    cell.src


    Ich hoffe man meinen schematischen Explorer-Aufbau erkennen.


    Wo hab ich da jetzt den Fehler versteckt?

  • Bin mir nicht sicher, aber wo sich das Programm "Abbruch" im Verzeichnisbaum "Programme" befindet, ist hier wohl nicht relevant.
    Vielmehr stimmt was im Programmablauf nicht.
    Schau mal ob Du damit weiter kommst:
    -> Gibt die Hilfefunktion mittels Fehlernummer (Fehlermeldung kommt ja nicht nur als Text, oder?) irgendetwas her?
    -> In welcher Programmzeile steht denn der Satzzeiger beim Hängen?
    -> Läßt sich eine Fehlerliste öffnen?


    viel Erfolg

    never touch a running system

  • Hallo Held,


    Mein Tip wäre die INI Falte im Interruptprogramm Abbruch() das das Problem verursacht.
    Da drin werden über das UP bas() Sachen initialisiert, die in Interruptroutinen genau zu solchen Fehlern führen.
    Braucht es da nicht.


    Gruss SJX

    Manche Maenner bemuehen sich lebenslang, das Wesen einer Frau zu verstehen. Andere befassen sich mit weniger schwierigen Dingen z.B. der Relativitaetstheorie.

  • Zitat

    Bei einigen Programmen passiert es tatsächlich, dass der Robbi mal eine halbe Sekunde Bedenkzeit braucht


    man muss hier aufpassen.


    hatten mega Probleme,
    weil der Robi ca. 600ms für die Reaktion gebraucht hat (angeblich).


    Nach Aufzeichnungen und Versuchen:
    wenn der Roboter wartet,....
    schaltet er seine Antriebe ab und befindet sich nicht mehr in der Regelung.
    Wenn nun die "wait-Anweisung" erfüllt ist,
    braucht er ca. 600ms um loszufahren....


    Lösung:
    while (NOT($in[1]))
    LIN wartepos
    endwhile

Erstelle ein Benutzerkonto oder melde dich an um zu kommentieren

Du musst ein Benutzerkonto haben um einen Kommentar hinterlassen zu können

Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen. Geht einfach!
Neues Benutzerkonto erstellen
Anmelden
Du hast bereits ein Benutzerkonto? Melde dich hier an.
Jetzt anmelden