Detecting a serial port valid after disconnect/reconnect

44 ビュー (過去 30 日間)
Gavin
Gavin 2025 年 1 月 21 日 21:33
コメント済み: Gavin 2025 年 1 月 27 日 19:40
I asked before with a long question and got no answers, so let's keep it simpler.
Serial port is connected to Arduino
Arduino resets, so I need to:
1. Detect that it's gone without throwing an error
2. Reconnect
Results:
Connected and callback set
K>> app.Pico
ans =
Serialport with properties:
Port: "COM16"
BaudRate: 57600
NumBytesAvailable: 0
Hit reset on Pico get following error message ( but it doesn't stop my program from running)
Unable to detect connection to the serialport device. Ensure that the device is plugged in and create a new serialport object.
If there is no "keep alive" function for serial ports ( Walter Roberson in https://www.mathworks.com/matlabcentral/answers/1722140-cant-read-the-serial-port) then what is generating this error? How can I catch it without constantly checking the connection myself?
If I could trap the error here that would be a great start.
So let's look at where we are:
K>> app.PicoCom
ans =
Serialport with properties:
In 'testmeaslib:CustomDisplay:PropertyWarning',
data type supplied is incorrect for parameter {0}.
Not useful, but I can check it right?
K>> isvalid(app.PicoCom)
ans =
logical
1
Really? It's still valid? Let's try
K>> serialportlist("available")
ans =
1×2 string array
"COM1" "COM16"
OK, at least I can see it's back in the list of available ports. Is this the best (fastest) way to find out?
Also I can't check in the input call back because then it's too late. Error thrown already.
K>> delete(app.PicoCom)
K>> app.PicoCom
ans =
handle to deleted Serialport
K>> isvalid(app.PicoCom)
ans =
logical
0
At least once deleted it's not valid. Let's reconnect:
K>> app.PicoCom = serialport()
K>> app.PicoCom
ans =
Serialport with properties:
Port: "COM16"
BaudRate: 57600
NumBytesAvailable: 0
ByteOrder: "little-endian"
DataBits: 8
StopBits: 1
Parity: "none"
FlowControl: "none"
Timeout: 10
Terminator: "CR/LF"
Back to normal as soon as I add
K>> configureCallback(app.PicoCom,"terminator",@app.PicoInput);
So I think I've got recovery OK. How about detecting when coms are lost?
BTW serialportfind is only useful when teh prot is there. If it's missing then looking throws an error...
K>> serialportfind
ans =
Serialport with properties:
In 'testmeaslib:CustomDisplay:PropertyWarning',
data type supplied is incorrect for parameter {0}.
Apparently it's a valid question to ask, just not a useful answer.
K>> isvalid(serialportfind)'
ans =
logical
1
  3 件のコメント
Gavin
Gavin 2025 年 1 月 21 日 22:51
I'm using an Arduino, but NOT Matlab's Arduino module. Just the serial port. I don't want any ML hand holding or interference in my Arduino code.
Gavin
Gavin 2025 年 1 月 22 日 5:17
Now I'm really confused. I've been using my workaround to check if the port is connected and now...
K>> serialportlist
ans =
1×2 string array
"COM1" "COM16"
So the device is there, but
K>> serialportlist("available")
ans =
"COM1"
But either Windows or Matlab won't let me have it back!
Other than rebooting the computer is there a way to fix this trap?
I've limited the computer to only be alloweed to have 2 COM ports, the built in COM1 and my USB port to simplify things. Here's the code I'm using to check what's up and I'm getting code 3 returned. There but not there.
function b = CheckAvailPort(app) % v61 depends on 2 serial ports on system
% returns 0 if properly connected
ports = serialportlist("available");
portCT = size(ports,2);
if portCT == 2 % Not connected
delete(app.PicoCom); % Leaves a "valid" dead deleted port!
app.PicoCom = []; % Clean it up
app.RebootPicoButton.BackgroundColor = 'yellow';
b = 1; % one port to connect, Init will work
else
% Make sure we have a COM port if it seems to be connected
if portCT == 1
try % If PicoComm isn't a valid port this will fail
if regexp(app.PicoCom.Port, regexptranslate('wildcard', 'COM*'))
b = 0; % all good
app.RebootPicoButton.BackgroundColor = 'white';
else
app.RebootPicoButton.BackgroundColor = 'red';
b = 2; % Something strange, haven't seen this problem yet
end
catch
app.RebootPicoButton.BackgroundColor = 'red';
warningMessage = sprintf(...
'No Pico USB device. Check connection and that Pico LED is flashing.');
uialert(app.MouseOdor,warningMessage,"No Pico found", "Icon","error");
b = 3; % Maybe Arduino has the port, or Pico locked up and not seen by Windoze
end
else
warningMessage = sprintf(...
'Too many USB devices. This program will not work.');
uialert(app.MouseOdor,warningMessage,"Extra USB devices found.", "Icon","error");
b = 4;
end
end
end

サインインしてコメントする。

採用された回答

埃博拉酱
埃博拉酱 2025 年 1 月 22 日 1:40
You may want to set the ErrorOccurredFcn property of serialport:
S=serialport('COM4',9600);
S.ErrorOccurredFcn=@(varargin)disp(varargin);
  4 件のコメント
埃博拉酱
埃博拉酱 2025 年 1 月 22 日 10:10
The official documentation doesn't give a function signature for ErrorOccurredFcn, so you'll have to try it yourself. I don't know how many input arguments I need, too, so I used varargin to accept any number of arguments. You can also use varargin, or disp varargin like I did and see how many inputs there are.
Gavin
Gavin 2025 年 1 月 27 日 19:40
Thanks for the help. I hadn't understood if varargin was literal or something I have to substitute for. After experimenting it turns out this works:
app.PicoCom.ErrorOccurredFcn=@(~)app.PicoError
So it wants one to start but doesn't care about it. A little doc could go a long way.
So now that I trap the error when it occurs I can deal with it.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeSerial and USB Communication についてさらに検索

製品


リリース

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by