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

Ergebnis 1 bis 8 von 8

Thema: Probleme mit der Festo Motion Library

  1. #1
    Registriert seit
    04.01.2015
    Beiträge
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    Folgendes Problem:
    Ich versuche über das Bus-System CANopen einen CMMP-AS-C2-3A-M0 (Motorcontroller) über eine CPX-CEC-C1 (SPS) anzusteuern, beide Elemente sind von der Firma Festo.
    Hierzu verwende ich in Codesys provided by Festo (2.3.9.19) den Baustein CMMP_AS_CTRL aus der Library-Datei Festo_Motion.lib.
    Wenn ich die Bits manuell durch Forcen setze funktioniert alles, heißt: im Controller werden die Bits erkannt und der Motor bewegt sich entsprechend der Vorgaben.
    Auch, wenn ich eine entsprechende Sequenz starte, die alle Bits in der richtigen Reihenfolge setzt, funktioniert alles.
    Sobald ich aber versuche, das ganze automatisch anfahren zu lassen, reagiert der Controller nicht mehr darauf. Er erkennt zwar alle Bits und gibt auch das Ready-Signal aus, allerdings bewegt sich der Motor kein Stück.
    Wenn ich wiederum das entsprechende Bit, was die Sequenz starten soll, durch Forcen auf False setze und dann wieder auf True, läuft der Motor wieder.

    Danke schon mal im Voraus.
    Zitieren Zitieren Probleme mit der Festo Motion Library  

  2. #2
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.222
    Danke
    533
    Erhielt 2.697 Danke für 1.949 Beiträge

    Standard

    Hört sich ein wenig so an, als ob die beim Forcen durch das Aus-/Einschalten der Bits Flanken erzeugst (die der Systembaustein wahrscheinlich braucht). Bei automatischen Ablauf, wie auch immer du den programmiert hast, scheint das nicht so zu passieren. Geht es denn ein einziges Mal und dann nie wieder oder überhaupt nicht? Ich würde den Fehler eher nicht in der Lib suchen, sondern im eigenen Programm und das kann man hier nicht sehen.

    PS: Was meinst übrigens mit Bits manuell setzen? Hast di ein Programm geschrieben, in welchem die die Bits manuell setzt oder setzt du die Bits an der Schnittstelle des Bausteins oder was genau?
    Geändert von Ralle (04.01.2015 um 18:45 Uhr)
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  3. #3
    SpaeterVogel ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.01.2015
    Beiträge
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Um die Bits am Baustein zu setzen habe ich eine Sequenz aus Einschaltverzögerungen verwendet. Die Bits werden also nicht sofort gesetzt, sondern nach und nach. Diese werden auch im FCT als gesetzt angezeigt, also kommen sie auch beim Controller an.

  4. #4
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.222
    Danke
    533
    Erhielt 2.697 Danke für 1.949 Beiträge

    Standard

    Kannst du vielleicht mal den betreffenden Codeteil zeigen?
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  5. #5
    SpaeterVogel ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.01.2015
    Beiträge
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Die Bits sind an die entsprechenden Ein- & Ausgänge des Controllerbausteins gelegt.
    Die Sequenz wird hier also gestartet, wenn noch keine Referenzfahrt durchgeführt wurde (was nach einem Neustart der Fall ist) und leitet diese ein.
    Angehängte Grafiken Angehängte Grafiken

  6. #6
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.222
    Danke
    533
    Erhielt 2.697 Danke für 1.949 Beiträge

    Standard

    Möglicherweise werden die ersten Bits schon gesetzt, wenn der Servo selbst noch am Hochlaufen ist. Wenn "Drive_is_Referenced" fehlt, wird genau 1 Mal der Vorgang gestartet (Flanke in Servobaustein oder im Servo selbst), dann nie wieder. Klappt das nicht, weil der Servo noch nicht soweit war, passiert danach nie wieder etwas. Es gibt doch diverse Gegensignale vom Servo (Betriebsbereit, Servo in Halt, Servo bereit usw.) Es macht Sinn, diese Signale (soweit vorhanden) in diese "Kette" mit einzubauen. Außerdem am Anfang ein generelles Signal, dass anzeigt, dass der Servo hochgelaufen ist und die Maschine betriebsbereit sowie sicher. Auch hier, sollte der Sicherheitskreis den Servo nicht starten lassen, tut er das dann auch nach Zuschalten des Sicherheitskontaktes nicht mehr. Dieser Kontakt sollte ebenfalls ganz am Anfang eingebunden sein.
    Geändert von Ralle (05.01.2015 um 06:52 Uhr)
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  7. #7
    SpaeterVogel ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.01.2015
    Beiträge
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Im aktuellen Programm habe ich die Verzögerung für den Start des Controllers bereits berücksichtigt, ich hatte gestern leider nur eine frühere Version zur Verfügung und habe vergessen, dies zu erwähnen.

    Das genannte Problem konnte ich trotzdem beheben, indem ich einfach das Ready-Bit vom Controller-Baustein in die Bedingungen für den endgültigen Start einbezogen habe.
    Scheinbar reagiert der Controller mit der Freigabe ein wenig verzögert.

    Trotzdem danke für deine Hilfe.

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

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    nunja der Hochlauf ist eindeutig definiert und über alle Festo Antrieb annährend identisch über das FHPP Protokoll.

    Der Hochlauf sollte bei diesem Antrieb wie folgt aussehen:
    Code:
    170: (* Versorgungsspannung des Motorcontollers prüfen° *)
     IF my_CMMx_CTRL.SupplyVoltagePresent THEN
      my_CMMx_CTRL.Halt := TRUE; (* Halt Signal setzen falls Betriebsspannung vorhanden ist *)
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 180;
     ELSE
      my_ST_Error.eMsgSpace := emsOthers;
      nStep := nStep + 1000 + 2; (* logged 172 *)
     END_IF;
    180: (* Regelung einschalten *)
     IF my_CMMx_CTRL.HaltActive THEN
      my_CMMx_CTRL.EnableDrive := TRUE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 190;
     END_IF (* logged 181 *)
    190: (* Stop Signal setzen (Low active) *)
     IF my_CMMx_CTRL.DriveEnabled THEN
      my_CMMx_CTRL.Stop := TRUE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 200;
     END_IF (* logged 191 *)
    200: (* Prüfung ob Antrieb betriebsbereit ist *)
     IF  my_CMMx_CTRL.Ready THEN
      (* Prüfung ob Antrieb bereit für Auftrag *)
      IF my_CMMx_CTRL.AckStart THEN
       nStep := 1000 + nStep + 2; (* logged 202 *)
      (* Referenzfahrt ausführen falls Antrieb nicht referenziert ist *)
      ELSIF NOT my_CMMx_CTRL.DriveIsReferenced
       AND NOT my_CMMx_CTRL.AckStart
      THEN
       eStatus := easReferenceRun; (* Status "Referenzfahrt läuft" melden *)
       my_CMMx_CTRL.StartHoming  := TRUE;
       tTimeout := TIME() + tDefaultTimeout;
       nStep := 210;
      ELSE
       eStatus := easReadyForTask; (* Status "Bereit für Fahrauftrag" melden *)
       tTimeout := tDisarmTimeout;
       nStep := 300;
      END_IF;
     END_IF (* logged 201 *)
    210: (* Warten auf Bestätigung, dass Referenzfahrt gestartet wurde *)
     IF my_CMMx_CTRL.AckStart THEN
      my_CMMx_CTRL.StartHoming := FALSE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 220;
     END_IF (* logged 211 *)
    220: (* Warten auf negative Flanke von AckStart *)
     IF NOT my_CMMx_CTRL.AckStart THEN
      tTimeout := tDisarmTimeout; (* Timeout ausschalten da Referenzfahrt unter Umständen sehr lange dauern kann *)
      nStep := 230;
     END_IF; (* logged 221 *)
    230: (* Warten auf Rückmeldung, dass Antrieb referenziert ist *)
     IF my_CMMx_CTRL.DriveIsReferenced THEN
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 240;
     END_IF;
    240: (* Negative Flanke von AckStart abfragen *)
     IF NOT my_CMMx_CTRL.AckStart THEN
      tTimeout := tDisarmTimeout;
      nStep := 300;
     END_IF; (* logged 241 *)
    Dann ist der Controller bereit. Vorausgesetzt die Hardwareeingänge "Reglerfrg." "Endstufenfrg" und Spg ist gesetzt.

    Nun können die verschiedenen Betriebsarten ausgewählt werden:

    Code:
    310: (* Entsprechend des Kommandos Bewegung ausführen *)
    (* IF   nChangeOPM = 0
      AND NOT bOPMChangeRequired
     THEN*)
      CASE eCommand OF
       easStartAbsolute..easStartRelative: (* Positionierung ausführen *)
        my_CMMx_CTRL.OPM := 1; (* Positionierbetriebsart *)
        (* Bei Relativfahrt Flag an CMMx Baustein setzen *)
        my_CMMx_CTRL.AbsoluteRelative := eCommand = easStartRelative;
        (* Bewegung kann nicht ausgeführt werden da Antrieb nicht bereit *)
        IF nSetValueVelocity = 0 THEN
         eStatus := easErrDrive;
         nStep := 1000 + nStep + 5;
    
        ELSE (* Bewegung ausführen *)
         my_CMMx_CTRL.SetValuePosition := nSetValuePosition;
         rTemp := (DINT_TO_REAL(nSetValueVelocity) / DINT_TO_REAL(nMaxVelocity)) * 100; (* Umrechnung der Sollgeschwindigkeit in Prozentwert des Maximums *)
         my_CMMx_CTRL.SetValueVelocity := REAL_TO_USINT(rTemp);
         my_CMMx_CTRL.StartTask := TRUE;
         tTimeout := TIME() + tDefaultTimeout;
         nStep := 400;
        END_IF;
       easJogPos..easJogNeg: (* In positive Richtung joggen *)
        my_CMMx_CTRL.OPM := 1; (* Positionierbetriebsart *)
        my_CMMx_CTRL.JoggingPos := eCommand = easJogPos;
        my_CMMx_CTRL.JoggingNeg := eCommand = easJogNeg;
        tTimeout := tDisarmTimeout;
        nStep := 500;
    
       easStartVelocity:
        my_CMMx_CTRL.OPM := 9; (* Drehzahlregelung *)
        my_CMMx_CTRL.SetValueRotRamp := DINT_TO_SINT(nSetValueAcceleration);
        my_CMMx_CTRL.SetValueRotSpeed := nSetValueVelocity; (* Umrechnung hier nicht notwendig da die Sollwertvorgabe an RotSpeed nicht in Prozentwerten erfolgt *)
        my_CMMx_CTRL.StartTask := TRUE;
        tTimeout := TIME() + tDefaultTimeout;
        nStep := 600;
       easStartTorque:
        ;
      END_CASE;
     (*END_IF;*)
    
    (*****************************************************)
    (* Direktbetrieb Positionierung       *)
    (*****************************************************)
    400: (* Warten auf Bestätigung des Fahrbefehls *)
     IF my_CMMx_CTRL.AckStart THEN
      eStatus := easInMotion;
      my_CMMx_CTRL.StartTask := FALSE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 410;
     END_IF;
    410: (* Warten auf Rücksetzen der Bestätigung *)
     IF NOT my_CMMx_CTRL.AckStart THEN
      tTimeout := tDisarmTimeout;
      nStep := 420;
     END_IF;
    420:
     (* Weiterschaltbedingungen für Positionieraufträge *)
     (* Fall 1: Warten auf Erreichen des Ziels *)
     IF my_CMMx_CTRL.MC THEN
      eStatus := easMotionComplete; (* Meldung "Antrieb steht im Ziel" setzen *)
      tTimeout := tDisarmTimeout;
      nStep := 430;
     (* Fall 2: Positionierung anhalten und Restweg löschen *)
     ELSIF eCommand = easHaltDrive THEN
      my_CMMx_CTRL.Halt := FALSE;
      eStatus := easReadyForTask; (* Meldung "Antrieb bereit für neuen Auftrag" setzen *)
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 440;
     (* Fall 3: Positionierung weiter ausführen jedoch als Bereit für neuen Auftrag setzen *)
     ELSIF eCommand = easNewTask THEN
      eStatus := easReadyForTask; (* Meldung "Antrieb bereit für neuen Auftrag" setzen *)
      tTimeout := tDisarmTimeout;
      nStep := 300;
     END_IF;
    430: (* Warten auf Bestätigung des Fahrbefehls *)
     IF eCommand = easAckTask THEN
      eStatus := easReadyForTask; (* Meldung "Antrieb bereit für neuen Auftrag" setzen *)
      tTimeout := tDisarmTimeout;
      nStep := 300; (* Rücksprung zu Kommandoverteiler *)
     END_IF;
    440: (* Warten auf ausgeführten Halt *)
     IF NOT my_CMMx_CTRL.HaltActive THEN
      my_CMMx_CTRL.Halt := TRUE;
      my_CMMx_CTRL.ClearRemainingPosition := TRUE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 450;
     END_IF;
    450: (* Warten auf ausgeführten Halt *)
     IF my_CMMx_CTRL.HaltActive THEN
      my_CMMx_CTRL.ClearRemainingPosition := FALSE;
      tTimeout := tDisarmTimeout;
      nStep := 300;
     END_IF;
    
    (*****************************************************)
    (* Tippbetrieb           *)
    (*****************************************************)
    500: (* Warten auf Bestätigung, dass der Antrieb in entsprechende Richtung tippt.
      Sofort anhalten sobald das Kommando easAckMove kommt! *)
     IF   my_CMMx_CTRL.AckStart
      OR  eCommand = easAckTask (* Sofort Tippen abbrechen bei easAckTask *)
     THEN
      eStatus := easInMotion;
      tTimeout := tDisarmTimeout;
      nStep := 510;
     END_IF;
    510: (* Warten auf Kommando easAckMove dann Tippen stoppen *)
     IF eCommand = easAckTask THEN
      eStatus := easReadyForTask; (* Meldung "Antrieb bereit für neuen Auftrag" setzen *)
      my_CMMx_CTRL.JoggingPos := FALSE;
      my_CMMx_CTRL.JoggingNeg := FALSE;
      tTimeout := tDisarmTimeout;
      nStep := 300;
     END_IF;
    
    (*****************************************************)
    (* Direktbetrieb Drehzahlregelung      *)
    (*****************************************************)
    600: (* Warten auf Bestätigung des Fahrbefehls *)
     IF my_CMMx_CTRL.AckStart THEN
      eStatus := easInMotion;
      my_CMMx_CTRL.StartTask := FALSE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 610;
     END_IF;
    610: (* Warten auf Rücksetzen der Bestätigung *)
     IF NOT my_CMMx_CTRL.AckStart THEN
      tTimeout := tDisarmTimeout;
      nStep := 620;
     END_IF;
    620: (* Warten auf Bestätigung des Fahrbefehls *)
     IF eCommand = easAckTask THEN
      my_CMMx_CTRL.SetValueRotSpeed := 0; (* System anhalten *)
      my_CMMx_CTRL.StartTask := TRUE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 630;
     END_IF;
    630: (* Warten auf Bestätigung des Fahrbefehls *)
     IF my_CMMx_CTRL.AckStart THEN
      eStatus := easInMotion;
      my_CMMx_CTRL.StartTask := FALSE;
      tTimeout := TIME() + tDefaultTimeout;
      nStep := 640;
     END_IF;
    640: (* Warten auf Rücksetzen der Bestätigung *)
     IF NOT my_CMMx_CTRL.AckStart THEN
      eStatus := easReadyForTask; (* Meldung "Antrieb bereit für neuen Auftrag" setzen *)
      tTimeout := tDisarmTimeout;
      nStep := 300;
     END_IF;

Ähnliche Themen

  1. Motion Control Library
    Von Draco Malfoy im Forum Antriebstechnik
    Antworten: 28
    Letzter Beitrag: 17.06.2014, 09:04
  2. Antworten: 4
    Letzter Beitrag: 26.01.2014, 20:48
  3. Step 5 Probleme mit der S 5
    Von Prab im Forum Simatic
    Antworten: 37
    Letzter Beitrag: 01.08.2013, 08:30
  4. Antworten: 0
    Letzter Beitrag: 05.03.2013, 09:02
  5. Probleme mit der Kommunikation
    Von udo_39 im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 17.11.2011, 22:36

Lesezeichen

Berechtigungen

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