113 lines
4.3 KiB
Python
113 lines
4.3 KiB
Python
import time
|
|
import pyads
|
|
|
|
# ==========================================
|
|
# KONFIGURATION
|
|
# ==========================================
|
|
AMS_NET_ID = "5.17.17.136.1.1"
|
|
PLC_PORT = 851 # Standard SPS-Port (Port 851)
|
|
|
|
# Positionen & Parameter
|
|
POS_1 = 110.0 # Erster Zielpunkt [mm]
|
|
POS_2 = 10.0 # Zweiter Zielpunkt [mm]
|
|
VELOCITY = 50.0 # Geschwindigkeit [mm/s]
|
|
OVERRIDE = 100.0 # Override in %
|
|
PAUSE_TIME = 30.0 # Wartezeit im ausgeschalteten Zustand [s]
|
|
|
|
# ==========================================
|
|
# HILFSFUNKTIONEN
|
|
# ==========================================
|
|
def set_axis_power(plc, enable: bool):
|
|
"""Schaltet fbPower über die GVL-Variablen ein oder aus."""
|
|
state_str = "EIN" if enable else "AUS"
|
|
print(f"--> Schalte Achsfreigabe (Power): {state_str}")
|
|
|
|
plc.write_by_name('GVL.Axis1_Override', float(OVERRIDE), pyads.PLCTYPE_LREAL)
|
|
plc.write_by_name('GVL.Axis1_FeedFw', True, pyads.PLCTYPE_BOOL)
|
|
plc.write_by_name('GVL.Axis1_FeedBw', True, pyads.PLCTYPE_BOOL)
|
|
plc.write_by_name('GVL.Axis1_CmdPower', enable, pyads.PLCTYPE_BOOL)
|
|
|
|
# Einschwingzeit für Bestromung / Bremsenlüftung
|
|
time.sleep(0.3)
|
|
|
|
def move_to_position(plc, target_pos: float, velocity: float):
|
|
"""Setzt Zielparameter, erzeugt eine Flanke auf CmdMoveAbs und wartet auf Axis1_MoveDone."""
|
|
print(f"--> Starte Positionierung auf {target_pos:.1f} mm (Speed: {velocity:.1f} mm/s)...")
|
|
|
|
# 1. Zielwerte in die GVL schreiben
|
|
plc.write_by_name('GVL.Axis1_TargetPos', float(target_pos), pyads.PLCTYPE_LREAL)
|
|
plc.write_by_name('GVL.Axis1_Velocity', float(velocity), pyads.PLCTYPE_LREAL)
|
|
|
|
# 2. Positive Flanke für rTrigMove in der SPS erzeugen (HIGH -> LOW)
|
|
plc.write_by_name('GVL.Axis1_CmdMoveAbs', True, pyads.PLCTYPE_BOOL)
|
|
time.sleep(0.1)
|
|
plc.write_by_name('GVL.Axis1_CmdMoveAbs', False, pyads.PLCTYPE_BOOL)
|
|
|
|
# 3. Warten auf das gelatchte Signal GVL.Axis1_MoveDone
|
|
while True:
|
|
is_busy = plc.read_by_name('GVL.Axis1_Busy', pyads.PLCTYPE_BOOL)
|
|
is_move_done = plc.read_by_name('GVL.Axis1_MoveDone', pyads.PLCTYPE_BOOL)
|
|
is_error = plc.read_by_name('GVL.Axis1_Error', pyads.PLCTYPE_BOOL)
|
|
|
|
# Erfolgreicher Abschluss: Achse nicht mehr Busy UND MoveDone ist TRUE
|
|
if not is_busy and is_move_done:
|
|
print(f" Zielposition {target_pos:.1f} mm erfolgreich erreicht.")
|
|
break
|
|
|
|
if is_error:
|
|
err_id = plc.read_by_name('GVL.Axis1_ErrorID', pyads.PLCTYPE_UDINT)
|
|
raise RuntimeError(f"SPS/NC-Fehler bei der Fahrt! ErrorID: {err_id}")
|
|
|
|
time.sleep(0.05)
|
|
|
|
# ==========================================
|
|
# HAUPTPROGRAMM (ENDLOSSCHLEIFE)
|
|
# ==========================================
|
|
def main():
|
|
plc = pyads.Connection(AMS_NET_ID, PLC_PORT)
|
|
|
|
try:
|
|
plc.open()
|
|
print(f"Verbindung zu TwinCAT PLC ({AMS_NET_ID}:{PLC_PORT}) erfolgreich hergestellt.")
|
|
print("Starte Ablaufsequenz. Beenden jederzeit mit Strg+C.\n")
|
|
|
|
cycle = 1
|
|
while True:
|
|
print(f"--- ZYKLUS {cycle} ---")
|
|
|
|
# === TEIL 1: Fahrt auf 110 mm ===
|
|
set_axis_power(plc, enable=True)
|
|
move_to_position(plc, target_pos=POS_1, velocity=VELOCITY)
|
|
set_axis_power(plc, enable=False)
|
|
|
|
print(f"--> Warte {PAUSE_TIME:.0f} Sekunden...")
|
|
time.sleep(PAUSE_TIME)
|
|
|
|
# === TEIL 2: Fahrt auf 10 mm ===
|
|
set_axis_power(plc, enable=True)
|
|
move_to_position(plc, target_pos=POS_2, velocity=VELOCITY)
|
|
set_axis_power(plc, enable=False)
|
|
|
|
print(f"--> Warte {PAUSE_TIME:.0f} Sekunden...\n")
|
|
time.sleep(PAUSE_TIME)
|
|
|
|
cycle += 1
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n[ABBRUCH] Sequenz durch Benutzer gestoppt.")
|
|
except Exception as e:
|
|
print(f"\n[FEHLER] Laufzeitfehler: {e}")
|
|
finally:
|
|
# Sicherheitsschaltung beim Beenden oder Abbrechen
|
|
try:
|
|
plc.write_by_name('GVL.Axis1_CmdPower', False, pyads.PLCTYPE_BOOL)
|
|
plc.write_by_name('GVL.Axis1_CmdMoveAbs', False, pyads.PLCTYPE_BOOL)
|
|
print("Sicherheitszustand hergestellt (Achsfreigabe entzogen).")
|
|
except Exception:
|
|
pass
|
|
|
|
plc.close()
|
|
print("ADS-Verbindung geschlossen.")
|
|
|
|
if __name__ == '__main__':
|
|
main() |