Clear a persistent variable in a MATLAB Fcn block as serial object

Hello! I am using following code for read data from serial port:
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'));
Where 'only3' is my function that takes only the first 3 chars from a string. The problem is that communication does not terminate with simulation stopping. Switch case has no effect (I thought that it shuts down reading after an other run). How can I clear persistent variable 's' and reset the block after stopping?

回答 (3 件)

Paul
Paul 2014 年 2 月 26 日

0 投票

clear fcn

1 件のコメント

Marco
Marco 2014 年 2 月 27 日
I tried that but it returns an error:
Open failed: Port: COM12 is not available. No ports are available. Use INSTRFIND to determine if other instrument objects are connected to the requested device. Block Gyro/Serial Read (#59) While executing: State During Action
where #59 points to 'fopen(s)' command

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

Friedrich
Friedrich 2014 年 2 月 27 日
編集済み: Friedrich 2014 年 2 月 27 日

0 投票

Hi,
A MATLAB FCN Block is a bad idea here. Better would be a MATLAB LVL 2 S-function because you can better control your serial port. In the mdlStart you create your serial object and later in the mdlTerminate you close it propperly. In the mdlOutputs you calculate the signal as usual.

6 件のコメント

Marco
Marco 2014 年 2 月 27 日
I tried with S-Function level 2 but it was very slow or however it had not same performances like MATLAB Fcn.
Friedrich
Friedrich 2014 年 2 月 27 日
But at least it works ;)
Can you post your S-function here? Maybe something wasn't implemented efficiently.
Marco
Marco 2014 年 2 月 27 日
but I edited that because it did not work: (sorry for file instead code but question editor does not allow me to write a so long code); where before execution I must run this script to load configurations:
clear all ;
%For write operation
serobjw = serial('COM12') ; % Creating serial port object now its connected to COM12
%Set connection properties
serobjw.Baudrate = 9600; % Set the baud rate at the specific value
set(serobjw, 'Parity', 'none') ; % Set parity as none
set(serobjw, 'Databits', 8) ; % set the number of data bits
set(serobjw, 'StopBits', 1) ; % set number of stop bits as 1
set(serobjw, 'Terminator', '') ; % set the terminator value to newline
set(serobjw, 'OutputBufferSize', 16) ; % Buffer for write operation, default it is 512
set(serobjw,'InputBufferSize',16);
get(serobjw) ;
fopen(serobjw) ;
get(serobjw, 'Status') % Gets the status of connection if 'open' connection was established
Data arrives after some lag. I do not know if it is a "packing problem" (the sender have a int16 data and I convert/re-convert it using byte-pack/unpack block, fut with a MATLAB Fcn it works in real time.
Friedrich
Friedrich 2014 年 2 月 28 日
So you create the serial object on the ML side and then pass it in to the S-Fcn at each call. This sounds like overhead to me. What happens if you create the serial object in the mdlInitializeSizes and make it a global variable? In that way you don't need to pass it in every time the S-Fcn is called. Does the performance get better?
In addition you are currently using a LVL 1 S-Fcn. I don't know if there might be a performance difference between LVL 1 and LVL 2 S-fcn.
Marco
Marco 2014 年 2 月 28 日
Are you saying that I have to modify mdlInitializeSizes section as:
function [sys,x0,str,ts]=mdlInitializeSizes(stime)
global s
s = serial('COM12');
fopen(s)
sizes = simsizes;
sizes.NumContStates = 0;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 2;
sizes.NumInputs = 0;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1; % at least one sample time is needed
sys = simsizes(sizes);
x0 = [];
str = [];
ts = [stime 0];
end
??? In this way it should call object creation and opening only one time, is it?
Friedrich
Friedrich 2014 年 3 月 3 日
Yes. You open the serial port in the mdlInitializeSizes and close it in the mdlTerminate.

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

Ryan Livingston
Ryan Livingston 2014 年 4 月 2 日

0 投票

Another thought could be to use the serial port I/O blocks directly in Simulink. See the Blocks heading here:
I am not too familiar with them, but they may facilitate a simpler interface to your hardware.
These could perform the I/O and then you could process the data using the method of your choosing.

質問済み:

2014 年 2 月 26 日

回答済み:

2014 年 4 月 2 日

Community Treasure Hunt

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

Start Hunting!

Translated by