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 ?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top