Concatenate 3 bytes array of real time serial data into single precision

10 次查看(过去 30 天)
Hi all,
So in a nutshell. I have a continuous stream of data from 4 sensors through one USB (i did not build the hardware so I cannot make any changes there). I have 20 bytes packets, 4 start bytes that I don't need, a 4 byte time stamp, then 3x4 bytes of data (3 bytes from each sensor).
I use currentBuffer=fread(s1,20)
I then manually get the 3x4 bytes of data, e.g.: sensor1[ currentBuffer(9) currentBuffer(10) currentBuffer(11)]
Now I want to convert this 3 byte array into one single precision number...
Can anyone please help me with this??
Thank you

回答(2 个)

James Tursa
James Tursa 2014-6-27
编辑:James Tursa 2014-6-27
How is the data/number formatted in the 3-bytes? Is it a 24-bit signed integer using 2's complement encoding? Is it a 24-bit unsigned integer? Is it some type of floating point format?
You might see this related thread for converting 24-bit 2's complement strings:
E.g., if you have a 24-bit 2's complement integer to deal with, then basically you simply need to sign-extend the 24-bits into an equivalent 32-bit 2's complement integer format, then typecast & type conversion will finish the job.
But first we need to know what format the 3x4 bytes are in.
Also, note that since you don't specify the precision with fread, it will be doing 'uint8=>double' by default ... i.e., converting all of the uint8 bytes to double. My guess is you probably don't really want to do that if you have downstream byte manipulation to do. So I would suggest you use '*uint8' or '*int8' explicitly instead.
  4 个评论
Mariam Hassib
Mariam Hassib 2014-7-9
When I try
currentBuffer=fread(s1,20,'*int8');
I always get this error:
Invalid PRECISION specified. Type 'help serial/fread' for more information.
James Tursa
James Tursa 2014-7-9
'int8' is listed as an acceptable PRECISION string in the help doc, so I don't understand the error. However, maybe back off and try a more brute force approach just to see if we can recover the original bit pattern:
currentBuffer = fread(s1,20); % this apparently already works for you
currentBuffer = typecast(uint8(currentBuffer),'int8'); % brute force

请先登录,再进行评论。


Andreas
Andreas 2015-1-9
Hey, I have the same problem right now and I'm interested in how you solved it in the end.
The data I get is three bytes each (24 bit two's complement). The ADC has 8 channels, so after every fread I get 24 bytes (as a row vector). It is stored in a Nx24 array, where N is the number of samples. So the data for channel 1 is stored in adc(:,1:3) (1 is MSB; 3 is LSB), channel 2 is stored adc(:,4:6) and so on. I read the data with
fread(handle,24,'uint8'))
The way I do it now is very cumbersome and takes a lot of time to process.
for i=1:8
hex = [dec2hex(adc(:,1+(i-1)*3)) dec2hex(adc(:,2+(i-1)*3)) dec2hex(adc(:,3+(i-1)*3))];
bin = dec2bin(hex2dec(hex),24);
bin32 = [bin(:,[1 1 1 1 1 1 1 1]) bin ]; % add 8 bits depending on sign -> 32bits
val = double(typecast(uint32(bin2dec(bin32)),'int32'));
% do something with val
end
where i is the index for the current channel. I couldn't figure out a way to do it for all channels simultaneously.
This proposed solution does not work for me. For example
k = typecast([int8(-(adc(1,1)<0)) adc(1,1:3)],'int32');
where adc(1,1:3) = [0,9,10]. This should result in 154, but I get 168361984. After swapbytes(k) I get 2314. Also, when I try to compute this for the whole dataset
k = typecast([int8(-(adc(:,1)<0)) adc(:,1:3)],'int32');
I get
Error using typecast. The first input argument must be a vector.
Can someone help me out here? Thanks, Andy

类别

Help CenterFile Exchange 中查找有关 Data Type Conversion 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by