Serial callback in "byte" mode triggered even though no bytes are available to read

I am using a serial port object to control stepper motors like this:
sObject_motor = serialport('COM3',115200);
sObject_motor.Timeout = 2;
sObject_motor.ByteOrder = "little-endian";
configureCallback(sObject_motor,"byte",8,@FAS_serialReadCallbackFunction);
There should be always at least 8 bytes sent by the controller as a response to any command (assuming the communication is set up correctly).
According to the above the callback should be executed when there are at least 8 bytes in the buffer to read.
However I keep getting error like this (not always, but randomly):
Warning: Error occurred while executing the listener callback for event DataWritten defined for class asyncio.InputStream:
Error using FAS_serialReadCallbackFunction (line 5)
Expected input number 2, count, to be nonzero.
The line 5 in my callback function is just:
serialans = read(sObject,sObject.NumBytesAvailable,"uint8");
When I set up a break point at this line and peek at the NumBytesAvailable property indeed it shows that there are no bytes available to read.
But this function should be triggered only when there are at least 8 bytes availble to read!
This causes the communication to fail randomly.
I am using 'pause' command after issuing every command to the controler but still this does not seem right.
Any help or suggestions is much appreciated.

5 Comments

is it possible that it was called when a timeout occurred?
Not likely. I have now set up timeout to 20 secs (used to be 2). The error is thrown almost immediately on sending a command to serial port.
No, unfurtunately.
I have set a breakpoint inside the callback function (as desribed above) and it seems that it can be triggered, at least sometimes, by the pause function (sic!). I have a while loop and inside that loop there is a UDP object being queried every 5 sec:
while ~stable
stable = IsBBStable(uObject);
pause(5)
end
So I noticed an instance where the breakpoint apparently has been triggered by that pause function.
It doesn't make any sense to me. I tried investigating the code downstream, but to no avail.
Maybe some Mathworks engineer can say whether it makes sense or not.
I realize this is an old thread, but I may have an answer for you. The callback triggers are generated every time the triggering criteria are satisfied. So if you are triggering on 5 bytes and you receive 10, you get two invocations of your callback that get generated. If you read all 10 bytes in the first time through, then the NumBytesAvailable will be zero the next time around.
If you have fixed size packets, you won't have much of an issue. But if you get variable length packets, you may need to set the triggering numbe of bytes equal to the smallest packets you expect to see, which means you need to deal with the redundant callbacks when they occur.
To get around this I usually just do:
function my_serial_callback(serial_port, event)
%Serial callback for command serial port
if (~serial_port.NumBytesAvailable)
return; %Discard queued events handled earlier
end
%The rest of the code goes here.

Sign in to comment.

Answers (0)

Products

Release

R2020a

Asked:

SLV
on 8 Feb 2021

Commented:

on 10 Aug 2026 at 20:11

Community Treasure Hunt

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

Start Hunting!