From: Mark on
Hi.

I am trying to read from a device connected to the serial port and view the data as it is coming in in realtime. However, it takes quite a while to read a relatively small ammount of data, up to 20 seconds before the data is obtained. I am using the code below and have tried using, fcsanf, fread, fgets, but all are extremely slow. Is there any way I can view the data as itcomes in through the port (like in realterm or hyperterminal).

Thanks,

Mark.

s=serial('com4');
s.InputBufferSize = 48000;
fopen(s) % open com3

s.ReadAsyncMode = 'continuous';
fprintf(s,'*IDN?')

importedData = fscanf(s,'%s',48000);
%importedData = fread(s)

fclose(s)
From: Walter Roberson on
Mark wrote:
> Hi.
>
> I am trying to read from a device connected to the serial port and view
> the data as it is coming in in realtime. However, it takes quite a while
> to read a relatively small ammount of data, up to 20 seconds before the
> data is obtained. I am using the code below and have tried using,
> fcsanf, fread, fgets, but all are extremely slow. Is there any way I can
> view the data as itcomes in through the port (like in realterm or
> hyperterminal).

> s=serial('com4'); s.InputBufferSize = 48000;
> fopen(s) % open com3

> s.ReadAsyncMode = 'continuous';
> fprintf(s,'*IDN?')

> importedData = fscanf(s,'%s',48000);

fscanf() with '%s' format is going to read until it sees a whitespace
character or sees end of file. This would not be a suitable format if the
response might contain blanks or tabs.

> %importedData = fread(s)

fread() in that form is going to read until it sees end of file.

> fclose(s)

fread(s, s.BytesAvailable) would only read as many bytes as have actually
arrived. You would need to create a loop that processed or stored those bytes
and looped back again until end of file was detected, and if the available
byte count is 0 you may wish to pause() a bit of time to wait for more data.
You may also wish to program s.BytesAvailableFcnCount to a byte count,
s.BytesAvailableFcnMode to 'byte', and s.BytesAvailabelFcn to a callback
function handle; the callback would then be triggered when the designated
number of bytes had been received (note that additional bytes may arrive
between the time the callback is requested and the time the callback is served.)
From: Mark on
Walter Roberson <roberson(a)hushmail.com> wrote in message <hu8v12$fu1$1(a)canopus.cc.umanitoba.ca>...
> Mark wrote:
> > Hi.
> >
> > I am trying to read from a device connected to the serial port and view
> > the data as it is coming in in realtime. However, it takes quite a while
> > to read a relatively small ammount of data, up to 20 seconds before the
> > data is obtained. I am using the code below and have tried using,
> > fcsanf, fread, fgets, but all are extremely slow. Is there any way I can
> > view the data as itcomes in through the port (like in realterm or
> > hyperterminal).
>
> > s=serial('com4'); s.InputBufferSize = 48000;
> > fopen(s) % open com3
>
> > s.ReadAsyncMode = 'continuous';
> > fprintf(s,'*IDN?')
>
> > importedData = fscanf(s,'%s',48000);
>
> fscanf() with '%s' format is going to read until it sees a whitespace
> character or sees end of file. This would not be a suitable format if the
> response might contain blanks or tabs.
>
> > %importedData = fread(s)
>
> fread() in that form is going to read until it sees end of file.
>
> > fclose(s)
>
> fread(s, s.BytesAvailable) would only read as many bytes as have actually
> arrived. You would need to create a loop that processed or stored those bytes
> and looped back again until end of file was detected, and if the available
> byte count is 0 you may wish to pause() a bit of time to wait for more data.
> You may also wish to program s.BytesAvailableFcnCount to a byte count,
> s.BytesAvailableFcnMode to 'byte', and s.BytesAvailabelFcn to a callback
> function handle; the callback would then be triggered when the designated
> number of bytes had been received (note that additional bytes may arrive
> between the time the callback is requested and the time the callback is served.)

The data is coming in constantly and looks like this:

00353X 00421Y 11250Z, and there is no end of file (unless i plug out my device). Ideally I would like to do my analysis after each bunch of XYZ but I am forced to fill a buffer and do the analysis on that. This buffer takes about 15 seconds to fill and is very difficult to determine what instances of time the data occurs at. Is it possible to do this or is it possible to display the coms data the way it soes in real term?

Mark.
From: Walter Roberson on
Mark wrote:
> Walter Roberson <roberson(a)hushmail.com> wrote in message

>> fread(s, s.BytesAvailable) would only read as many bytes as have
>> actually arrived. You would need to create a loop that processed or
>> stored those bytes and looped back again until end of file was
>> detected, and if the available byte count is 0 you may wish to pause()
>> a bit of time to wait for more data. You may also wish to program
>> s.BytesAvailableFcnCount to a byte count, s.BytesAvailableFcnMode to
>> 'byte', and s.BytesAvailabelFcn to a callback function handle; the
>> callback would then be triggered when the designated number of bytes
>> had been received (note that additional bytes may arrive between the
>> time the callback is requested and the time the callback is served.)

> The data is coming in constantly and looks like this:
> 00353X 00421Y 11250Z, and there is no end of file (unless i plug out my
> device). Ideally I would like to do my analysis after each bunch of XYZ
> but I am forced to fill a buffer and do the analysis on that. This
> buffer takes about 15 seconds to fill and is very difficult to determine
> what instances of time the data occurs at. Is it possible to do this or
> is it possible to display the coms data the way it soes in real term?

Depends what you mean by "real time".

You could,

>> create a loop that processed or
>> stored those bytes and looped back again until end of file was
>> detected, and if the available byte count is 0 you may wish to pause()
>> a bit of time to wait for more data

And in the loop, you would use
>> fread(s, s.BytesAvailable)
which would
>> only read as many bytes as have
>> actually arrived.


Alternately,

>> You may also wish to program
>> s.BytesAvailableFcnCount to a byte count, s.BytesAvailableFcnMode to
>> 'byte', and s.BytesAvailabelFcn to a callback function handle; the
>> callback would then be triggered when the designated number of bytes
>> had been received (note that additional bytes may arrive between the
>> time the callback is requested and the time the callback is served.)

You could, if you wanted, set s.BytesAvailableFcnCount to 1 to get an
interrupt for every incoming byte (excluding perhaps bytes that had also
arrived by the time the interrupt service routine was run.)


Your current technique of using

fscanf(s,'%s',48000);

is going to try to read 48000 _strings_ not 48000 _characters_ . One string
would be, for example, 00353X and then 00421Y would be a second string because
strings end at whitespace such as blanks. So don't do that ;-)
From: Jan Houska on
Hi Mark,

Mark wrote:
.... <snip>
> The data is coming in constantly and looks like this:
>
> 00353X 00421Y 11250Z, and there is no end of file (unless i plug out my
> device). Ideally I would like to do my analysis after each bunch of XYZ
> but I am forced to fill a buffer and do the analysis on that. This
> buffer takes about 15 seconds to fill and is very difficult to determine
> what instances of time the data occurs at. Is it possible to do this or
> is it possible to display the coms data the way it soes in real term?

It is easy to do this with Real-Time Windows Target Packet Input and
Stream Input blocks if you are willing to switch from MATLAB code to
Simulink block diagram. You may want to check the "rtpacketio" and
"rtstreamio" demos, they do more or less exactly this.

Jan


--
Jan Houska HUMUSOFT s.r.o.
houska(a)humusoft.com Pobrezni 20
http://www.humusoft.com 186 00 Praha 8
tel: ++ 420 284 011 730 Czech Republic
fax: ++ 420 284 011 740