问题
After problems I had here, I need some help to write a function with MATLAB Function block. I saw in following links that some people solved it with that block or s-function: http://www.mathworks.co.uk/matlabcentral/newsreader/view_thread/317910
http://www.physicsforums.com/showthread.php?t=595813
http://www.mathworks.de/matlabcentral/newsreader/view_thread/250266
So I tried with this:
function y = fcn(u)
coder.extrinsic('only3')
coder.extrinsic('serial', 'fopen','fread')
coder.extrinsic('set')
persistent s a
y = (zeros(2,1));
s = serial('COM12');
set(s,'Terminator','', 'InputBufferSize', 1024);
a = char('000'); % a-initialization for mxArray problems
a = only3(get(s,'status')); %to check if port is already opened calling custom function
if strncmp(a,'clo',3)==true
fopen(s)
else
fclose(s)
end
y = fread(s,[2 1],'uint8'); % I have to read some data from serial. This command works fine in the matlab command window.
Where only3
is a function that I created. It takes first 3 char from a string, and I need it to compare only three char of the 'status'
answer:
function let = only3(string)
let = string(1:3);
I did it to know if communication is already opened. But simulink returns me an error as window:
Call to MATLAB function aborted: Open failed: Port: COM12 is not available. No ports are available.
I think it tries to open the port after port opening in the first iteration.
EDIT: I change my code with this:
function y = fcn(u)
coder.extrinsic('only3')
coder.extrinsic('strncmp') %like Phil say
coder.extrinsic('serial', 'fopen','fread')
coder.extrinsic('get')
persistent s a b
y = (zeros(2,1));
%%Part taken from Phil suggestion:
if isempty(s)
% only do this the first time
s = serial('COM12','Terminator','', 'InputBufferSize', 1024);
a = '000';
b = false; %without this returns mxArray error.
end
a = only3(get(s,'status'));
b = strncmp(a,'clo',3);
if b == true
fopen(s)
else
fclose(s)
end
y = fread(s,[2 1],'uint8');
It returns as error:
Unsuccessful read: OBJ must be connected to the hardware with FOPEN. Block MATLAB Function (#24) While executing: State During Action
hightlighting y
expression.
UPDATE EDIT: I solved it with following code:
function y = fcn(u)
coder.extrinsic('only3')
coder.extrinsic('strncmp')
coder.extrinsic('serial', 'fopen','fread')
coder.extrinsic('get')
persistent s a b
y = uint8(zeros(2,1)); %signal is an uint8
if isempty(s)
% only do this the first time
s = serial('COM12','Terminator','', 'InputBufferSize', 1024);
a = '000';
b = false;
a = only3(get(s,'status'));
b = strncmp(a,'clo',3);
switch double(b)
case 1
fopen(s);
otherwise
fclose(s);
end
end
y = uint8(fread(s,[2 1],'uint8'));
But, as I commented below, every time that I stop simulation I have to restart Matlab because it does not close communication. I say this because if I re-try to start simulation it returns "my first error":
Call to MATLAB function aborted: Open failed: Port: COM12 is not available. No ports are available.
I do not know why. There would be something that runs fclose(s)
every simulation stopping like mdlTerminate
function in M-code Level-1 S-functions. Some suggestion ?
回答1:
Your initialization of the persistent variables is wrong. Presumably what you really want is
persistent s a
if isempty(s)
% only do this the first time
s = serial('COM12');
a = '000';
end
回答2:
if your port is not closed, you can use the instrfind
command to get the array of intruments, then you can use fclose
to close the comunication.
I.e.
q=instrfind();
%%select
the index port that you want to close.
fclose(q(x)); where x is the index
And if you need to clear all the instruments, use delete(q);
Best regards.
来源:https://stackoverflow.com/questions/21957839/some-help-writing-a-s-function-to-read-data-from-serial-port