Serial Receive Block Variable Data Size

6 次查看(过去 30 天)
Hi,
I’m working with a data logger that sends measurements over a USB serial interface. I’d like to read the data using Simulink’s Serial Receive block, but I’m running into a problem: the block requires a fixed message length, while my measurements vary in digit count, so each message can be longer or shorter.
I’ve tried setting a maximum data size, but then the block misses the terminator since it relies solely on the fixed length. I’ve also experimented with a smaller fixed size in non-blocking mode, buffering incoming bytes and then parsing complete messages—but approaches that i tried introduce delays that are unacceptable for my application.
I’d appreciate any suggestions or solutions to handle variable-length serial messages in Simulink without significant latency.

回答(1 个)

Anjaneyulu Bairi
Anjaneyulu Bairi 2025-7-3
Hey,
Currently, the Serial Receive block in the Instrument Control Toolbox does not support string outputs or variable-size outputs. Depending on your workflow, there are alternative methods for reading the data:
  • You can use a MATLAB Function block that leverages MATLAB's serialport functionality to read the data.
  • Alternatively, you can configure the Serial Receive block to read the data as a stream of uint8 values. These can then be buffered and converted to strings outside of the block. To do this, set the data type to uint8, disable the header and terminator, and specify a fixed output size. Keep in mind that, depending on the output size you specify, the data from the block may not contain a complete NMEA string and could span across multiple NMEA strings.
Hope this helps!
  1 个评论
Cihanoglu
Cihanoglu 2025-7-3
编辑:Cihanoglu 2025-7-3
Hi thanks for the answer,
I’m having trouble using serialport and serial objects with Simulink—they’re not supported for code generation. In MATLAB, I can read the data with these just fine, but my application requires working within Simulink.
The data logger sends messages already in uint8 format. I don’t convert them to strings because Simulink code generation doesn’t support string functions, so I parse the data directly in uint8.
I'm using no terminator, no header, and a fixed maximum size. This allows me to receive the data, but the messages get shifted. For example, the block expects 36 bytes. If I send only 24, the remaining 12 bytes are missing, and the message shifts by 12 bytes in every cycle.
Currently, I use a buffer: I collect each message into the buffer and only output messages that match the correct format. However, this introduces delays and doesn’t always work reliably. Because the control parameters for the right format shifts also.
I’m attaching my buffer code and example input messages and output messages.
function [lineOut, lenOut, valid] = CRLFStreamParser(dataIn,count)
MAX_BUF = int32(512);
MAX_LINE = int32(256);
CR = uint8(13);
LF = uint8(10);
persistent buf bufLen
if isempty(buf)
buf = zeros(MAX_BUF,1,'uint8');
bufLen = int32(0);
end
lineOut = zeros(MAX_LINE,1,'uint8');
lenOut = int32(0);
valid = false;
lastNZ = int32(0);
for i = int32(count):-1:1
if dataIn(i)~=0
lastNZ = i;
break;
end
end
n = min(lastNZ, MAX_BUF - bufLen);
if n>0
d = dataIn(1:n);
buf(bufLen + (1:n)) = d(:);
bufLen = bufLen + n;
end
endIdx = int32(0);
for i = int32(1):(bufLen-1)
if buf(i)==CR && buf(i+1)==LF
endIdx = i+1;
break;
end
end
if endIdx>0
lenOut = min(endIdx, MAX_LINE);
lineOut(1:lenOut) = buf(1:lenOut);
valid = true;
rem = bufLen - endIdx;
if rem>0
buf(1:rem) = buf(endIdx+1:bufLen);
end
bufLen = rem;
end
end

请先登录,再进行评论。

产品


版本

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by