#id driveTurntablePositioning.py 2024-10-29 rev3 oh # Fullmo MovingCap CODE - micropython example. # original file name: driveTurntablePositioning.py # Beispielanwendung: 2 Positionen anfahren über einen Kontakt import sys import mcdrive as mc # Welcher Eingang steuert die Bewegung? IN_MOVEMENT = 1 # Welcher Ausgang für Rückmeldung? OUT_CONFIRM = 1 # Zusätzliche Wartezeit am Anfang, damit Antrieb nicht unmittelbar losläuft INITIAL_WAIT_TIME_MS = 5000 # Applikationsparameter APP_PARAMETERS = """ 050.3511h.05h,integer32,0 # HOME delay 050.3511h.06h,integer32,180 # HOME velocity 050.3511h.07h,integer32,500 # HOME acceleration 050.3511h.08h,integer32,0 # HOME POSITION [°] 050.3511h.09h,integer32,500 # HOME deceleration 050.3511h.0ah,integer32,1000 # HOME max current / torque 050.3512h.05h,integer32,0 # POS1 delay 050.3512h.06h,integer32,180 # POS1 velocity 050.3512h.07h,integer32,500 # POS1 acceleration 050.3512h.08h,integer32,170 # POS1 POSITION [°] 050.3512h.09h,integer32,500 # POS1 deceleration 050.3512h.0ah,integer32,1000 # IN2 max current / torque 050.3513h.05h,integer32,2000 # BASE RotaryRefFlankTime [ms] 050.3514h.05h,integer32,200 # POS1 RotaryTurnFlankTime [ms] 050.3515h.05h,integer32,150 # IN Time Tolerance Window +/- [ms] 050.3516h.05h,integer32,600 # HOME Out Flank Time [ms] 050.3517h.05h,integer32,600 # POS1 Out Flank Time [ms] 050.6067h.00h,unsigned32,1 # Target Reached Window [user units] 050.6068h.00h,unsigned16,200 # Target Window Time [ms] 050.607dh.01h,integer32,0 # Softlimit - Min Pos [user units] 050.607dh.02h,integer32,360 # Softlimit - Max Pos [user units] 050.60f2h.00h,unsigned16,192 # Positioning option code """ # Grundinitialisierung: Motorparameter, Getriebe/Skalierung, Sicherstellen, dass keine IN-Funktionen aktiv MOTOR_PARAMETERS = """ 050.3401h.03h,unsigned32,1 # Pos Control Window 050.3401h.15h,unsigned16,1000 # Acc. Torque [0.1%] 050.3401h.16h,unsigned16,1000 # Dec. Torque [0.1%] 050.3401h.18h,unsigned16,1000 # Stall Torque [0.1%] 050.3511h.01h,unsigned16,0 # IN1 function 050.3512h.01h,unsigned16,0 # IN2 function 050.3513h.01h,unsigned16,0 # IN3 function 050.3514h.01h,unsigned16,0 # IN4 function 050.3515h.01h,unsigned16,0 # IN5 function 050.3516h.01h,unsigned16,0 # IN6 function 050.3517h.01h,unsigned16,0 # IN7 function 050.3518h.01h,unsigned16,0 # IN8 function 050.3611h.01h,unsigned16,0 # OUT1 function 050.3612h.01h,unsigned16,0 # OUT2 function 050.3613h.01h,unsigned16,0 # OUT3 function 050.3614h.01h,unsigned16,0 # OUT4 function 050.6073h.00h,unsigned16,1000 # Max. Current/Torque [0.1%] 050.6091h.01h,unsigned32,5 # Motor revolutions 050.6091h.02h,unsigned32,1 # Shaft revolutions 050.6092h.01h,unsigned32,360 # Feed 050.6092h.02h,unsigned32,1 # Shaft revolutions """ def WriteObjectsFromKickdriveList(kickdriveTxtExportString): # Erstelle eine Liste mit Parametern params = [line.split(',') for line in kickdriveTxtExportString.split('\n') if line.strip()] # Gehe durch jede Teile for param in params: # Falls es keine ID gibt, überspringe diese Zeile if len(param) < 2: continue id = param[0].split('.') index = int(id[1].rstrip('h'), 16) subindex = int(id[2].rstrip('h'), 16) value = int(param[2].split('#')[0]) # Schreibe das Objekt mc.WriteObject(index, subindex, value) print ("Writing object " + hex(index) + "," + hex(subindex) + " = " + str(value)) def MeasureInHighTime(): # warten bis IN1 high wird while (mc.ChkIn(IN_MOVEMENT) == 0): sys.wait(1) startTime = sys.time() # warten bis IN1 low wird while (mc.ChkIn(IN_MOVEMENT) == 1): sys.wait(1) endTime = sys.time() # Zeitspanne zwischen IN1 high und low return (endTime - startTime) def WaitAndConfirm(confirmTime): # Sicherstellen, dass Antrieb unterwegs ist sys.wait(10) # Prüfe Status auf In Position / "target reached" while (mc.ChkReady() == 0): sys.wait(1) # Fahre nur fort, wenn kein Fehler vorliegt while (mc.ChkError() != 0): sys.wait(1) # Setze Ausgang für festgelegte Dauer mc.SetOut(OUT_CONFIRM) sys.wait(confirmTime) mc.ClearOut(OUT_CONFIRM) def ExecuteInputFunction(fctNo, inputNo): """Löse Funktion aus mit den Parametern, die bei hinterlegt sind. siehe https://movingcap.de/webmanuals/eth/index.html?eingaenge-simulieren.html :param fctNo: Eine MovingCap-Eingangsfunktion von 1-9 :type fctNo: int :param inputNo: Die Input-Nummer aus dem die Parameter verwendet werden sollen, von 1-10 :type inputNo: int """ mc.WriteObject(0x3510, 2, fctNo + inputNo * 256) WriteObjectsFromKickdriveList(MOTOR_PARAMETERS) WriteObjectsFromKickdriveList(APP_PARAMETERS) mc.ClearOut(OUT_CONFIRM) sys.wait(INITIAL_WAIT_TIME_MS) # and go... while(1): signalTime = MeasureInHighTime() homeTime = mc.ReadObject(0x3513, 5) # Object 3513h.05h legt die IN1-Flankenzeit für die Fahrt auf Start/Refposition fest. pos1Time = mc.ReadObject(0x3514, 5) # Object 3514h.05h legt die IN1-Flankenzeit für die Fahrt auf Zielpos fest. tolerance = mc.ReadObject(0x3515, 5) # Object 3515h.05h ist das Toleranzfenster +/- für die beiden oberen Werte. # IN1 Dauer war im Bereich der Start/Homeposition ("Referenzfahrt") if (signalTime > (homeTime - tolerance) and signalTime < (homeTime + tolerance)): # "Timed Motion Absolute" mit Parametern aus IN1 / 3511h.x ExecuteInputFunction(4, 1) # warte auf Erreichen Zielposition, bestätige mit Dauer wie in Parameter 3513h.06h eingestellt confirmTime = mc.ReadObject(0x3516, 5) WaitAndConfirm(confirmTime) # IN1 Dauer war um Bereich der Zielposition elif (signalTime > (pos1Time - tolerance) and signalTime < (pos1Time + tolerance)): # "Timed Motion Absolute" mit Parametern aus IN2 / 3512h.x ExecuteInputFunction(4, 2) # warte auf Erreichen Zielposition, bestätige mit Dauer wie in Parameter 3514h.07h eingestellt confirmTime = mc.ReadObject(0x3517, 5) WaitAndConfirm(confirmTime)