Detecting a serial port valid after disconnect/reconnect

15 次查看(过去 30 天)
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
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
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
You may want to set the ErrorOccurredFcn property of serialport:
S=serialport('COM4',9600);
S.ErrorOccurredFcn=@(varargin)disp(varargin);
  4 个评论
埃博拉酱
埃博拉酱 2025-1-22
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
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 个)

产品


版本

R2024b

Community Treasure Hunt

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

Start Hunting!

Translated by