serialport hickup for certain data
古いコメントを表示
Hi together,
I'm using the MATLAB serialport interface to communicate with a Thorlabs Elliptec ELL18 piezo stage. This can be controlled using the serial interface provided by the USB connection. The documentation of the specific format can be found here:
https://www.thorlabs.com/Software/Elliptec/Communications_Protocol/ELLx%20modules%20protocol%20manual.pdf (see page 5 in particular)
Im prinicple one can send commands like "1gs", which will invoke the "get status" command on device "1" connected to the serial bus.
In my case I have two devices connected to the same bus (called "0" and "1") and I'm encountering inconsistent behaivior for some very specific commands in a specific order:
- a "move to 8.2 degrees command" to stage 0 (0ma00000CC1)
- a "move to 346.5 degrees command" to stage 1 (1ma00021B00)
Notice that the specific angles (or binary values in the command) are important. For other combinations it works fine.
The commands themselves are correct; they even work in MATLAB. If I run them out of order or, if I issue "get status" commands in between everything works fine.
But this code will fail 99% the time:
%% Connect
BAUD_RATE = 9600;
DATA_BITS = 8;
STOP_BITS = 1;
PARITY = 'none';
HANDSHAKE = false;
ENDIAN = 'big-endian';
Terminator = 'CR/LF';
com_handle = serialport('COM13',...
BAUD_RATE,...
'DataBits', DATA_BITS,...
'ByteOrder', ENDIAN,...
'Parity', PARITY,...
'StopBits', STOP_BITS,...
'Timeout', 10);
com_handle.configureTerminator(Terminator)
%% Send "get status" commands (just as an example)
write(com_handle,'1gs','string');
result = readline(com_handle);
disp(result) % expected result is 1GS00
%% Move stage 0 to 8.2 0ma00000CC1
write(com_handle,'0ma00000CC1','string');
result = readline(com_handle);
disp(result); %expected result is 0PO00000CBE
%% Move stage 1 to 346.5 1ma00021B00
write(com_handle,'1ma00021B00','string');
result = readline(com_handle);
disp(result) %expected result is 1PO00021AFE, but this never happens...
It will hickup during the last readline with the warning:
Warning: The specified amount of data was not returned within the
Timeout period for 'readline'.
'serialport' unable to read any data. For more information on
possible reasons, see serialport Read Warnings.
I tried the following things:
- Adding various delays in between the read and write (Like pause(0.1) between every command)
- Made sure that there is no FlowControl (its not allowed / supported here)
- Waiting until NumBytesAvailable is > 0 (which never happens after the last command)
- Using different terminators
- Looked at the output of getpinstatus (which give 0 for all the result fields)
- Reconnecting inbetween the commands (!)
- Made sure that there is no specific mechanical problem at the specified locations for the stages
The only solution which I found that reliably works is to issue "get status" commands in between the movement commands. This however should not be necessary according to the manual and slows the process down.
There is another weird quirk: If I execute the code in the debugger (step by step) it also works :'(
I then tried this virtually identical Python code:
import serial
with serial.Serial('COM13', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1) as ser:
ser.write("1gs\r\n".encode())
print(ser.readline())
ser.write("0ma00000CC1\r\n".encode())
print(ser.readline())
ser.write("1ma00021B00\r\n".encode())
print(ser.readline())
which works all of the time. The software "ELLO" which is provided with the stages also allows to run commands in a specific order. This indeed works fine.
This brings me to the conclusion that the device itself is functioning correctly but something in the MATLAB serialport state-machine is causing a hickup. I'm out of ideas here and can't find any other setting to try with the serialport interface. I'm also massively puzzled why it happens with this particular set of commands, but not with the millions of others that we have run before.
Maybe someone has any hints?
Thanks a lot!
2 件のコメント
Arfor Houwman
2024 年 1 月 9 日
I'm having exactly the same issue with the ELL14 rotation mount. Did you find a solution in the end?
Max M
2025 年 7 月 6 日
回答 (1 件)
Lindsey
2025 年 7 月 2 日
This is reliably working for setting up the com handle and one example serial command using Thorlabs Elliptec ELL18 piezo stage. the only change from Max was changing '1gs' to '0gs'. if left with the '1gs'. I receive the same error as Max and Arfor.
%% Connect
BAUD_RATE = 9600;
DATA_BITS = 8;
STOP_BITS = 1;
PARITY = 'none';
HANDSHAKE = false;
ENDIAN = 'big-endian';
Terminator = 'CR/LF';
com_handle = serialport('COM3',BAUD_RATE,'DataBits', DATA_BITS,...
'Parity',PARITY,...
'ByteOrder', ENDIAN,...
'StopBits', STOP_BITS,...
'Timeout', 10);
com_handle.configureTerminator(Terminator)
%% Send "get status" commands (just as an example)
write(com_handle,'0gs','string');
result = readline(com_handle)
disp(result) % expected result is 0GS00
%% Move stage 0 to 8.2 0ma00000CC1
write(com_handle,'0ma00000CC1','string');
result = readline(com_handle)
disp(result); %expected result is 0PO00000CBE
1 件のコメント
カテゴリ
ヘルプ センター および File Exchange で Serial and USB Communication についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!