Concatenate 3 bytes array of real time serial data into single precision
Show older comments
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
Answers (2)
James Tursa
on 27 Jun 2014
Edited: James Tursa
on 27 Jun 2014
1 vote
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 Comments
Mariam Hassib
on 30 Jun 2014
James Tursa
on 5 Jul 2014
Edited: James Tursa
on 5 Jul 2014
Assuming you have 3 bytes of a 24-bit 2's complement signed integer with the order of bytes 9-10-11 being MSB to LSB:
First, keep the original bit pattern intact by reading as an int8, e.g.,
currentBuffer=fread(s1,20,'*int8');
Then, sign extend your three bytes and typecast to a 32-bit integer, e.g.,
k = typecast([int8(-(currentBuffer(9)<0)) currentBuffer(9:11)],'int32')
Depending on your system, you may need to do swapbytes(k) also.
If you need a floating point number then wrap above in single( ).
Mariam Hassib
on 9 Jul 2014
James Tursa
on 9 Jul 2014
'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
on 9 Jan 2015
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
Categories
Find more on Logical 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!