- ticker: --spin mode polls FPRD until payload changes (phase-locks processing to TwinCAT frame arrival instead of free-running ticker), timeout at 1.5 periods keeps loop alive on master stop - verified: 238k cycles, 0 errors, exec=245us (FPWR-bound), TwinCAT PLC task confirmed at 2000.8 Hz (all three tasks 0.5ms; base tick was already 50us - no base-time change needed) - docs: 500us latency plan; scripts: task-rate ADS probe, 2kHz deploy, UI automation experiments (pywinauto) for task cycle inspection
47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
import sys, time
|
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
|
from pywinauto import Application
|
|
from pywinauto.mouse import click
|
|
|
|
app = Application(backend='uia').connect(process=1456, timeout=10)
|
|
win = app.window(title_re='.*TcXaeShell.*')
|
|
tree = win.descendants(control_type='Tree')[0]
|
|
|
|
def find_item(item, name):
|
|
try:
|
|
item.expand(); time.sleep(0.25)
|
|
except Exception:
|
|
pass
|
|
try:
|
|
for ch in item.children():
|
|
if ch.window_text() == name:
|
|
return ch
|
|
r = find_item(ch, name)
|
|
if r is not None:
|
|
return r
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
for task_name in ['PlcTask', 'PlcTask1', 'PlcTask2']:
|
|
node = None
|
|
for root in tree.children():
|
|
node = find_item(root, task_name)
|
|
if node:
|
|
break
|
|
if not node:
|
|
print(f'{task_name}: NOT FOUND'); continue
|
|
node.iface_expand_collapse.Expand()
|
|
r = node.rectangle()
|
|
click(coords=(int((r.left + r.right) / 2), int((r.top + r.bottom) / 2)))
|
|
time.sleep(1.5)
|
|
vals = {}
|
|
for e in win.descendants(control_type='Edit'):
|
|
try:
|
|
aid = e.automation_id()
|
|
if aid in ('1054', '1058', '1055', '1057', '1516', '1061'):
|
|
vals[aid] = e.get_value()
|
|
except Exception:
|
|
pass
|
|
print(f"{task_name}: name={vals.get('1054')} port={vals.get('1058')} prio={vals.get('1055')} ticks={vals.get('1057')} ms={vals.get('1516')}")
|