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
Pregunta
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 ?
Solución
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
Otros consejos
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.