Open pl-deassis opened 2 years ago
Hi!
Could you please attach the code that generates the error and the error message together with the stack trace? The problem shows up when you are trying to connect, right? Could you also make sure that you're using the latest pylablib version (1.4.0)? There have been some adjustments in several recent version regarding Thorlabs APT communication.
One option you can try is to use a more generic KinesisDevice
class and supply is_rack_system=True
to its constructor. If it connects without an issue, you can check some device-level methods like get_device_info
and channel-level methods like _get_position
(mind the underscore!) to see if any of them work.
Regarding the serial numbers: it's normally just used to double-check the model provided by the device itself and does not affect the behavior. Generally, the class behaves pretty much the same way for any motor, except for a couple of built-in scaling coefficients.
Hello Alex! Thanks for the quick reply.
I am using a freshly installed pylablib, on a newly created environment just for it.
I start by making a
stage_list = Thorlabs.list_kinesis_devices()
, which runs without error. A print(stage_list)
returns
[('55263504', 'Kinesis K10CR1 Rotary Stage'), ('70262594', 'APT Stepper Motor Controller')]
Here is the code to create the BSC 203 object:
bsc = Thorlabs.KinesisDevice('70262594')
, which runs without any error message.
Here is what I get when asking for full device info:
bsc.get_full_info()
Traceback (most recent call last):
File "C:\Users\aaa\AppData\Local\Temp\ipykernel_4612\29980927.py", line 1, in <cell line: 1> bsc.get_full_info()
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\core\devio\interface.py", line 239, in get_full_info return self._get_device_variables(["settings","status","info"],include=include)
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\core\devio\interface.py", line 195, in _get_device_variables info[k]=g()
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\devices\Thorlabs\kinesis.py", line 206, in get_device_info data=self.query(0x0005,dest=dest).data
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\devices\Thorlabs\kinesis.py", line 168, in query return self.recv_comm(expected_id=replyID)
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\devices\Thorlabs\kinesis.py", line 141, in recv_comm msg=self.instr.read(6)
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\core\devio\comm_backend.py", line 45, in wrapped return func(self,*args,**kwargs)
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\core\devio\comm_backend.py", line 34, in wrapped return func(self,*args,**kwargs)
File "C:\Users\aaa\.conda\envs\Automation\lib\site-packages\pylablib\core\devio\comm_backend.py", line 922, in read raise self.Error("read returned less data than expected")
ThorlabsBackendError: backend exception: 'read returned less data than expected' ('read returned less data than expected')
By the way, the rotation stage works without any issue, even if displacements are still taken in steps, instead of degrees (which I believe is the expected behavior).
Thanks for the info!
Could you try running
bsc = Thorlabs.KinesisDevice('70262594', is_rack_system='auto')
print(bsc._is_rack_system)
print(bsc.get_device_info())
print(bsc._get_position())
and see if any of these lines work?
Regarding K10CR1: it uses a different hardware setup, so it generally communicates without issues. If you want to use degrees instead of steps for the displacement (and, correspondinly, velocity and acceleration), you can specify scale='stage'
in the constructor, i.e., you would need to create it as
k10cr = Thorlabs.KinesisMotor('55263504', scale='stage')
A couple more comments:
is_rack_system=True
instead of is_rack_system='auto'
; this should work better.Hello Alex,
Your suggestion for the BSC203 worked, but only when using is_rack_system=True
. I can now communicate with it, but giving commands to the drives is still very unstable. I got one of the three motors to move, once, but mostly they just sit there. I sometimes get error messages. For instance, I used _get_position(channel=1)
and got an error, because the controller sent back 0x0464 (move completed) instead of 0x0412 (the result of get poscounter).
I also tried using ._home(channel=X)
for X = 1, 2, and 3, but nothing happened.
I'm glad that at least general communication works! The rest should be easier to figure out now.
To make things easier for now, I'd suggest editing Lib\site-packages\pylablib\devices\Thorlabs\kinesis.py
in your Python folder and replace lines 998-999
, which currently should read
def __init__(self, conn, scale="step"):
super().__init__(conn)
with
def __init__(self, conn, scale="step", default_channel=1, is_rack_system=False):
super().__init__(conn,default_channel=default_channel,is_rack_system=is_rack_system)
With that change, you can get back to using more advanced KinesisMotor
class with the same rack system specification:
bsc = Thorlabs.KinesisMotor('70262594', is_rack_system=True)
This way you don't have to put underscores for all the methods. It also properly handles messages like 0x0464
, so it should work more stable now.
Regarding motion and homing, I have a couple of suggestions:
get_velocity_parameters
, get_jog_parameters
, and get_homing_parameters
methods. Keep in mind that by default the velocities are reported in steps/s, so the numbers should be pretty high.get_limit_switch_parameters
method and make sure that they agree with the settings in Thorlabs Kinesis.get_status
method and make sure that everything is fine there. Normally you would see "homed"
, "moving_fw"
, "moving_bk"
, or "homing"
there, but nothing else. If there are other statuses present (e.g., "sw_bk_lim"
or "sw_fw_lim
indicating backward/forward limit switches), that might indicate some problems."homed"
). To override this behavior, use bsc.home(force=True)
.Let me know if any of this helps, and if any problems remain.
Hello again, Alex.
While general comms are working, the handling of channels is not. I noticed the code you wrote sets channel 1 as default. I imagine the numbering of channels goes 0, 1, 2, corresponding to physical channels 1, 2, and 3. Indeed Channel 2 did respond to some commands, such as move_by
, but failed to respond to home
. After a while it stopped responding to commands and I had to power cycle the controller.
When I ran bsc.get_status()
, I got ["homed","tracking","enabled"]
, so it seems there are still problems to solve. I tried using all commands with the (channel = )
argument, but no matter what I chose, everything went to channel 1.
Here's the result of a get_full_info()
:
{'velocity_parameters': TVelocityParams(min_velocity=0.0, acceleration=8191940.005849554, max_velocity=8193082.172131147), 'jog_parameters': TJogParams(mode='step', step_size=204800, min_velocity=0.0, acceleration=204796.22766257636, max_velocity=409654.1169895678, stop_mode='profiled'), 'homing_parameters': THomeParams(home_direction='reverse', limit_switch='reverse', velocity=409654.1169895678, offset_distance=40960), 'gen_move_parameters': TGenMoveParams(backlash_distance=4096), 'limit_switch_parameters': TLimitSwitchParams(hw_kind_cw='make', hw_kind_ccw='make', hw_swapped=False, sw_position_cw=1228800, sw_position_ccw=409600, sw_kind='ignore'), 'position': 10240000, 'status': ['homed', 'tracking', 'enabled'], 'cls': 'KinesisMotor', 'conn': {'port': '70262594', 'baudrate': 115200, 'bytesize': 8, 'parity': 'N', 'stopbits': 1, 'xonxoff': 0, 'rtscts': True}, 'device_info': TDeviceInfo(serial_no=70000000, model_no='BSC203', fw_ver='2.3.3', hw_type=32, hw_ver=2, mod_state=0, nchannels=3, notes='APT Stepper Motor Controller'), 'channel': [1], 'scale_units': 'step', 'scale': (1, 53.68, 0.0110011792), 'stage': 'step'}
The fact that I only get one set of parameters makes me thing that while it does understand that there are three channels, only one is actually being recognized. Is there a way to create three objects, one for each channel?
Update:
The bsc.blink(channel = n)
command works properly for n = 1, 2, and 3. However, for the move_by
command, channel = 1 actually drives channel 2, and n = 3 returns an error message.
I noticed that the blink
command sends a comm to dest = "host"
, while move_by
sends comm data to dest = ("channel",n)
.
I did some checks with simulated devices, and it looks like I was misunderstanding how the channels work for these multi-rack systems. Evidentally, they are selected only via the destination address (dest
parameter), while the command channel parameter is set to 1. This is why the second channel, for which channel=1
, worked, while others didn't.
I have modified the code, and here you can get the new version of kinesis.py
. Simply replace your current version with this one. In addition, it fixes the channels numbering issue (which now go from 1), and adds a method .set_supported_channels
, which lets you specify the number of channels on your system. This way get_full_info
method woudl return the data on all the axes, not just the first one, and most methods can take channels='all'
, which makes them execute simultaneously for all channels.
Let me know if this works for you, and if any issues remain. Also, if the devices continues to occasionally stop responding, could you see if there is any pattern, e.g., if it always stops after a particular command?
Hello, please tell me who used the thorlabs_aptdevice library how to correctly call the status method to get the position in millimeters!
I know pyLabLib wasn't tested on the Thorlabs BSC 203, but when I can see it when I ask for a list of Thorlabs APT devices. However, whenever I try to communicate with it I get an error, stating that it sent less information than was expected. The thorlabs_apt_device 0.3.4 package recommends enabling virtual comm ports, but I don't know if that would be the case for pyLabLib.
I noticed in kinesis.py that the program should recognize a serial number starting in 70 as a BSC.03, but couldn't find specific code related to that... In any case it does correctly identify the serial number of my device, so it is getting some sort of communication through.
Has anyone experienced this sort of issue? I would be happy to (try to) contribute with BSC 203 support, and pointers on where to start and what to adapt would be greatly appreciated.