MC_Stop in TwinCat3 stoppt nicht

corbillat18

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

aktuell bin ich dabei, einen Notaus an meiner Anlage (CX9020 mit TwinCat3, Schrittmotorklemmen EL7041) zu integrieren.
Der Notaus wird aktuell an jeder Stelle im Programm durchgeführt, allerdings tritt eine Verzögerung auf, wenn ich die Achsen verfahren lassen.
D.h. ich verwende den Baustein MC_MoveAbsolute und lasse die Achse fahren. Zum Test wird nun der Notaus gedrückt und meine Notausroutine startet. Der Baustein MC_Stop wird auf aktiv geschaltet (Execute := TRUE) und die Ausgänge Busy und Done springen auf TRUE, obwohl die Achse noch bis zum Ende des zuvor eingestellten Fahrauftrags fährt. Wenn ich frühzeitig (noch in der Beschleunigungsphase) den Notaus drücke, wird die Achse etwas früher gestoppt.
Da ich die Achsen ohne Schleppabstandüberwachung betreibe, ergibt sich für mich nun die Frage, ob es daran liegen kann, dass der MC_Stop-Baustein ohne Schleppabstandüberwachung nicht richtig funktioniert?
Meine Werte für die Decelleration und den Jerk habe ich bereits hoch gesetzt, sodass sie weit über den Defaultwerten des MoveAbsolute-Befehls liegen. Die Bremsrampe sollte also entsprechend schnell zum Stillstand führen. Auch in den Achseinstellung ist der Maximalwert für die Decelleration entsprechend angepasst. Habe ich weitere Einstellungen übersehen? In der Dokumentation finde ich leider keine weiteren Werte, die ich abändern könnte.
Falls ich den MC_Stop-Befehl an der gleichen Stelle durch ein MC_Reset ersetze stoppt die Achse im übrigen sofort..

Wäre super, falls ihr da eine Lösungsidee oder andere Vorschläge habt! Danke!
 
MC_Stop: Die Achse wird gleichzeit für alle für andere Bewegungskommandos gesperrt. Erst wenn nach dem vollständigen Stop das Execute-Stop auf FALSE gesetzt wird kann die Achse wieder gestartet werden (vorher ist in der AxisRef das Bit NcToPlc.StateDWord.MotionCommandsLocked gesetzt). Die Entriegelung der Achse nach der fallenden Flanke von Execute benötigt wenige Zyklen. Während dieser Phase bleibt das Busy-Signal TRUE und der FB muss weiter aufgerufen werden bis Busy = FALSE gesetzt ist.

Done und Busy sind nicht gleichzeitig anliegend. In deiner Beschreibung liest es sich aber so.

Ansonsten kann ich mit den vorhandenen Infos erst mal da nicht weiterhelfen.

Workarround. Klicker mal in der NC-Achse auf den Eingängen des Drives herum.
In der Beschreibung gibt es irgend wo etwas bzgl. Fast Axis Stop. Hierbei wird ein Eingang per EA-link (vom benutzer) dann in den Stop gezwungen.
Ich habe es nicht direkt vor mir, das mapping erfolgt glaube ich auf nDataIn4.

Guga
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der MC_Stop bildet da eine Ausnahme unter den MC-Bausteinen (Eine Ausnahme ist das Bewegungskommando MC_Stop. Dieses setzt „Done“ auf TRUE, sobald die Achse gestoppt ist. Dennoch bleiben „Busy“ und „Active“ TRUE, da die Achse verriegelt wird. Erst nachdem Execute = FALSE gesetzt wird, wird die Achse entriegelt und „Busy“ sowie „Active“ auf FALSE gesetzt.

Der Fast Axis Stop wär tatsächlich eine Möglichkeit..
Trtozdem wäre es interessant zu wissen, was den MC_Stop an der Ausführung hindert..
 
@TE: Hast Du auch sicher MC_Stop genommen und nicht aus versehen MC_Halt? Hast die Werte von Deceleration und Jerk auch an den Baustein vor der Ausführung, bzw. direkt im Kommando übergeben?
Nachtrag: Die Werte für Deceleration und Jerk müssen nicht angegeben werden, in dem Fall nimmt er die Werte des letzten Fahrbefehls, sie müssen aber größer/gleich den Werten des letzten Fahrbefehls sein, ansonsten nimmt der Baustein die Werte des letzten Fahrbefehls.
 
Zuletzt bearbeitet:
Mein Aufruf sieht wie folgt aus:

Code:
fbStop_x : MC_Stop ;
...
______________________________________________


fbStop_x(    Axis := Achse_x_Teststand, 
                    Execute := TRUE, 
                    Deceleration := 500000, 
                    Jerk := 100000,
                    busy => bxbusy, 
                    Done => bxStop,
                    CommandAborted => bCommandAborted_x_Teststand,
                    Error => bError_x_Teststand) ;

Wie gesagt wird der Aufruf auch abgearbeitet, aber leider reagiert die Achse erst verzögert
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hm, ich habe das gerade mal auch mit so utopischen Werten getestet und hier wurde der Befehl sofort ausgeführt. Übrigens machen Deine Werte für Deceleration und Jerk nur Sinn, wenn der Motor das auch kann, ansonsten wird TC3 denke ich die Werte nehmen die bei der Achse unter Parameter als Maximalwerte konfiguriert sind.
Gib doch bitte mal etwas mehr Code Preis, vielleicht kann man dann mehr sehen. Ich habe den Verdacht, dass der FB gar nicht ausgeführt wird.
Ist in Deinem Programm denn Execute immer auf True? Der Baustein muss auch mal mit False ausgeführt werden um die Achse wieder freizugeben, außerdem reagiert der Baustein nur bei einer positiven Flanke.
 
Zuletzt bearbeitet:
FB_Prozess:

Code:
CASE iZustandProzesse OF 
...:
...:

iZustand_Fahrt_1: 
          
    fbKinematik.fbAchse_x.fbAchse_x_Teststand_MoveAbsolute(Axis := fbKinematik.fbAchse_x.Achse_x_Teststand,
                                                            Position := fPos_Ueberlauf, 
                                                            Velocity := 1000, 
                                                            BufferMode := MC_Aborting , //MC_Buffered,
                                                            Execute := TRUE,
                                                            Done => bPos_x_Erreicht) ;    
    IF bPos_x_Erreicht = TRUE  AND NOT bNotaus THEN
            bPos_x_Erreicht := FALSE ;
            iZustandProzess := iZustand_Pneumatik ;
    ELSIF bNotaus THEN
        fbKinematik.fbAchse_x.fbAchse_x_Teststand_MoveAbsolute(Axis := fbKinematik.fbAchse_x.Achse_x_Teststand, Execute := FALSE) ;
        iFehlerzustand := iZustandProzess ;
        iZustandProzess := iZustand_Notaus ;
    END_IF

...:
...:
iZustand_Notaus:
 fbNotaus(bNotausroutine := TRUE) ;

END_CASE

FB_Notaus:
Code:
CASE iZustandNotausroutine OF
//===========================================================================================
0:    (*Warten auf Start der Notausroutine*)

    IF bNotausroutine = TRUE THEN
            iZustandNotausroutine := 10 ;
    END_IF

//===========================================================================================
10:    (*Stoppen aller aktiven Komponenten*)

    // Anhalten der Kinematik
    fbStop_x(    Axis := fbKinematik.fbAchse_x.Achse_x_Teststand, 
                                        Execute := TRUE, 
                                        Deceleration := 50000000, 
                                        Jerk := 10000000,
                                        busy => bxbusy, 
                                        Done => bxStop,
                                        CommandAborted => bCommandAborted_x_Teststand,
                                        Error => bError_x_Teststand) ; 
        //Notlösung, da MC_Stop nicht funktioniert
        //fbReset_x(Axis := fbKinematik.fbAchse_x.Achse_x_Teststand, Execute := TRUE);

        IF bxbusy = TRUE AND bxStop = TRUE THEN
        iZustandNotausroutine := 20 ;

20:
         ....
30:

          //MC_Stop zuruecksetzen
          fbStop_x(Axis := fbKinematik.fbAchse_x.Achse_x_Teststand, Execute := FALSE, busy => bxbusy);
          ...
40:

          //Variablen zuruecksetzen
          bxbusy := FALSE ;
          bxStop := FALSE ;

...:

END_CASE

Der auskommentierte Reset (fbReset_x) in FB_Notaus funktioniert an der Stelle und sorgt für ein abruptes Anhalten der Achse zum gewünschten Zeitpunkt. Der MC_Stop wird auch ausgeführt, nur stoppt die Achse erst nach Beendigung des Fahrauftrags. Beim fbStop_x Baustein wird mir der Executeeingang solange als FALSE angezeigt, bis ich den Notaus betätige - eine steigende Flanke ist also vorhanden..

Inzwischen ist meine Vermutung, dass sich der MC_Stop sich nur auf den Sollwert der Position bezieht. Nachdem ich den Schleppabstand ja nicht überwache (und eventuell der Sollwert bereits am Ziel angekommen ist sobald ist drücke), könnte es sein, dass der MC_Stop lediglich einen Stop der Sollposition übergibt?
 
Nur mal schnell drübergesehen und evtl. nicht richtig verstanden. Trotzdem mal ein erster Gedanke:

Werden die Achsenfunktionen nur innerhalb der State-Machine aufgerufen oder handelt es sich hier nur um Aufrufe zur Parameterübergabe?
Gerne stolpere ich selbst auch darüber, das ich den Funktionsbaustein bedingt aufrufe und mich wundere warums nicht geht. Gelegentlich ist so schon der Keim gelegt, das Flanken eben nicht erkannt werden.

Das nur mal so als Einwurf im Bezug auf den ersten Gedanken, der oft nicht der schlechteste ist ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo corbillat18,
Du machst da gleich mehrere Fehler. Erstmal rufst Du den FB in der CASE-Anweisung auf, das ist ein absolutes NoGo. Innerhalb einer CASE-Anweisung oder einer If-Abfrage setzt man die Eingänge des Bausteins, der Aufruf erfolgt jedoch außerhalb. Nur in ganz großen Ausnahmefällen ist es OK, dies auch innerhalb solcher Anweisungen/Abfragen zu machen, z.B. wenn man einen Zähler im selben Zyklus wieder starten möchte kommt man nicht drum herum den Zähler einmal mit False zu starten. Dann wird bei Deinem Programm der MC_Stop nur einen Zyklus ausgeführt, was auch nicht funktioniert, da dieser Zyklisch ausgeführt werden muss und last but not least ist der Eingang Execute bei Dir immer True, dadurch läuft MC_Stop, wenn überhaupt, nur einmal, da er nur auf eine steigende Flanke reagiert.
 
Zurück
Oben