Numerical Issues unpacking binary data string
5 views (last 30 days)
Show older comments
Maximilian Becker
on 20 Aug 2021
Commented: Maximilian Becker
on 24 Aug 2021
Hi,
Iam using the "Packet Input" block to receive data from an Arduinoa Due via serial connection. The device sends a binary data packet consisting of 13 bytes, where the first byte is a header and the other 12bytes represent 3 float values of 4bytes each.
I am using the following matlab function inside a matlab function block to reorder the 12 bytes and compose the 3 single values (single values are equivalent to float values here). Afterwards I cast this single to a double to work with it:
function singleV = uint8ToSingle(uintArray)
% initilize some variable to avoid matching size errors
singleV = zeros(1,3);
uintArray_1 = zeros(1,4);
uintarray_2 = zeros(1,4);
uintarray_3 = zeros(1,4);
% split the 12bytes uint8 data array into the 4byte arrays
uintArray_1 = uintArray(1:4);
uintArray_2 = uintArray(5:8);
uintArray_3 = uintArray(9:12);
% cast the 4 uint8 values to one single value each
uint8Value_1 = typecast(uint8(uintArray_1),'single');
uint8Value_2 = typecast(uint8(uintArray_2),'single');
uint8Value_3 = typecast(uint8(uintArray_3),'single');
% cast the single value to double values
singleV_1 = double(uint8Value_1);
singleV_2 = double(uint8Value_2);
singleV_3 = double(uint8Value_3);
%combine the 3 values into one array
singleV = [singleV_1,singleV_2,singleV_3];
A simulink example is attached to this post.
Now to the problem: This algorithm seems to be working fine for almost all the time, but sometimes the numerical value I am extracting explodes from a range of ~[-2 , 2] to something in the order of >10^10, which causes problems for the rest of the program:
when you zoom in:
when you zoom out:
Does anyone know how to "remove the outliers" in real time or how to handle this problem otherwise?
Thanks in advance.
Best regards,
Max
0 Comments
Accepted Answer
Jan Houska
on 20 Aug 2021
Hi Max,
first, you may be missing a very useful feature of the Packet Input block that allows it to output the signals directly as the data types you need. This is done using the Block Output Data Types parameter. Currently, you are likely using '13*uint8' to get a vector of 13 bytes that you later convert by the MATLAB function. Instead, you can use {'uint8', '3*single'} and the block will now have two data output ports, the first one returning the first byte and the second one returning the three single values as a vector. This feature should allow you to eliminate the MATLAB function completely. And, if you prefer to have three separate ouput ports for each of the single values, you can use {'uint8', 'single', 'single', 'single'} .
As to the outliers, these may be caused by an undetected error in the received data or by converting incomplete data. So they actually may be eliminated or reduced by using the built-in conversion present in the Packet Input block. If they are not, the solution depends on what you want to do with such an outlier value. E.g., if you are fine with limiting it to the range -2 to 2, the Saturation block will do that. If you want some other handling, like replacing it with the value read in the previous step, this can be also done, but will require several blocks to do that.
Good Luck, Jan
1 Comment
More Answers (1)
Jan Houska
on 24 Aug 2021
Hi Max,
saturation is by far the simplest method, although I understand it has its limitations. The next simplest method is to repeat the previous value if the current value is out of range. Please find attached a simple model that does this using an Enabled Subsystem that passes its input to the output when enabled and holds its output when disabled. The enable signal is generated according to the requested condition, this time the signal being in the range -2 to 2.
Good Luck, Jan
See Also
Categories
Find more on Target Computer Setup in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!