代码拉取完成,页面将自动刷新
#!/usr/bin/python3
import re, serial
from motion_controllerui import MainUI
import threading, time
ports = {'crystal': 'COM7',
'source': 'COM5',
'detector': 'COM6',
}
baudrate = 9600
timeout = 0.01
axes = ['x', 'y', 'z']
step = 2.5e-3
def serial_operation(func):
def wrapper(port, *args, **kwargs):
try:
with serial.Serial(port, baudrate, timeout=timeout) as ser:
return func(ser, *args, **kwargs)
except:
time.sleep(timeout)
wrapper(port, *args, **kwargs)
return wrapper
def ser_communicate(ser, command):
ser.write(command.encode('utf-8'))
resp = ser.readline().decode('utf-8')
print(f'{ser.name} {command} {resp}')
@serial_operation
def read_position(ser):
positions = []
for axis in axes:
ser.write(f'?{axis.capitalize()}/'.encode('utf-8'))
resp = ser.readline().decode('utf-8')
if resp:
positions.append(round(int(re.findall('[+-]?\d+', resp)[0]) * step, 4))
else:
positions.append(0)
return positions
@serial_operation
def move(ser, axis, dist, absolate=False):
command = f'{axis.capitalize()}={dist/step:.0f}/' if absolate else f'{axis.capitalize()}:{dist/step:.0f}/'
if re.search(':0/|:-0/', command):
print(f'Skip {ser.name} {command}')
else:
ser_communicate(ser, command)
@serial_operation
def stop(ser):
command = 'S0/'
ser_communicate(ser, command)
@serial_operation
def reference(ser, mod='set'):
for axis in axes:
command = {'set': f'HM{axis.capitalize()}/',
'move': f'{axis.capitalize()}=0/'}
ser_communicate(ser, command[mod])
class Main(MainUI):
def __init__(self, master=None):
super().__init__(master)
self.running = True
self.variables = {}
for name in ports:
for axis in axes:
self.variables[f'{name}_{axis}_relative'] = self.builder.get_variable(f'{name}_{axis}_relative')
self.variables[f'{name}_{axis}'] = self.builder.get_variable(f'{name}_{axis}')
self.variables[f'{name}_{axis}_setter'] = self.builder.get_variable(f'{name}_{axis}_setter')
self.builder.get_object(f'Button_{name}_{axis}_-')['command'] = lambda name=name, axis=axis: move(ports[name], axis, -self.variables[f'{name}_{axis}_relative'].get(), absolate=False)
self.builder.get_object(f'Button_{name}_{axis}_+')['command'] = lambda name=name, axis=axis: move(ports[name], axis, self.variables[f'{name}_{axis}_relative'].get(), absolate=False)
self.builder.get_object(f'Button_{name}_{axis}_set')['command'] = lambda name=name, axis=axis: move(ports[name], axis, self.variables[f'{name}_{axis}_setter'].get(), absolate=True)
self.builder.get_object(f'Button_stop')['command'] = lambda: [stop(ports[name]) for name in ports]
self.builder.get_object(f'Button_set_ref')['command'] = lambda: [reference(ports[name], mod='set') for name in ports]
self.builder.get_object(f'Button_to_ref')['command'] = lambda: [reference(ports[name], mod='move') for name in ports]
self.mainwindow.protocol('WM_DELETE_WINDOW', self.on_closing)
threading.Thread(target=self.auto_read_positions, args=()).start()
def auto_read_positions(self):
while self.running:
for name in ports:
positions = read_position(ports[name])
if positions and self.running:
for axis, position in zip(axes, positions):
self.variables[f'{name}_{axis}'].set(position)
time.sleep(1)
def on_closing(self):
self.running = False
self.mainwindow.destroy()
if __name__ == "__main__":
app = Main()
app.run()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。