How to convert a 24 bit, two’s complement value into a signed integer?

I want to read an AD converter using the Raspberry Pi SPI interface controlled by Matlab. The AD converter outputs 24 bit data in the two's complement format, MSD first. The Matlab writeRead command returns the data as a row vector of data type char
How can I quickly translate the data into an integer of data type int32 ?

8 Comments

How to I convert a 64 bit, two's complement value(binary vector)[ 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] into a signed integer?
>> typecast(uint8(bin2dec(char(reshape(A,8,[]).' + '0'))),'int64')
ans =
int64
-65
P=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1] if we are taking 2's complement for this binary vector, we have to get -3 as answer.
swapbytes(typecast(uint8(bin2dec(char(reshape(P,8,[]).' + '0'))),'int64'))
Dear Walter Roberson, Thank you for your reply. I am expecting -3 as answer, it is working fine for me if p=16 bit two's complement number ( using w=typecast(uint16(bi2de(w)),'int16')) but when p=64 bit two's complement number, it is not giving correct answer as -3. And the function "swapbytes(typecast(uint8(bin2dec(char(reshape(P,8,[]).' + '0'))),'int64'))" not giving correct answer.
>> P=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1]
P =
Columns 1 through 23
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Columns 24 through 46
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Columns 47 through 64
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
>> swapbytes(typecast(uint8(bin2dec(char(reshape(P,8,[]).' + '0'))),'int64'))
ans =
int64
-3
Looks like -3 to me.
Thank you very much for your timely help Walter Roberson.

Sign in to comment.

 Accepted Answer

s = 2's complement 24-bit string to convert
b = [s([1 1 1 1 1 1 1 1]) s]; % sign extension
k = typecast(uint32(bin2dec(b)),'int32'); % equivalent decimal number

5 Comments

Thank you for your reply. Please elaborate on what the statement " b = [s([1 1 1 1 1 1 1 1]) s];" does.
From your description, you said you had a 24-bit binary string that represented a 2's complement formatted integer value. To convert that into an equivalent 32-bit binary string one only has to extend the left-most bit (i.e., the "sign" bit) all the way to fill out the 32-bit string. That is what the statement above does ... repeats the left-most "sign" bit and appends it to the front of the original string, effectively extending the "sign" bit eight times to fill out the 32-bit string. The usual MATLAB conversions can then complete the process of obtaining the decimal int32 value. The syntax used is equivalent to:
b = [s(1) s(1) s(1) s(1) s(1) s(1) s(1) s(1) s];
I understand it now. Thank you for explanation.
This is also very helpful to me. However I have one question. When you say 24-bit string you mean something like 0bxxxxxxxxxxxxxxxxxxxxxxxx or a 24-bit hex string like 0xaaaaaa ?
This is is obviously a 24-bit binary string. Hence the extension by 8 bits to 32 bits.

Sign in to comment.

More Answers (1)

There is an example MATLAB class in Raspberry Pi support package that does something similar for MCP300x ADC's. Here is the readVoltage() method for this class:
function voltage = readVoltage(obj, adcChannel)
validateattributes(adcChannel, {'numeric'}, ...
{'scalar', '>=', 0, '<=', obj.NumAdcChannels-1}, '', 'adcChannel');
adc = obj.getAdcChannelSelect(adcChannel);
data = uint16(obj.spiObj.writeRead([1, adc, 0]));
highbits = bitand(data(2), obj.Lsb2);
voltage = double(bitor(bitshift(highbits, 8), data(3)));
voltage = (obj.VoltageReference/1024) * voltage;
end
where obj.Lsb2 is defined as bin2dec('00000011'). The value read from ADC is 10-bits stashed into two 8-bit values. The upper two-bits is in byte 2 and the 8 least significant bits are in byte 3.
You can take a look at the entire class definition here:
<Support package installe dir>\raspi\+raspi\+internal\mcp300x.m

1 Comment

Thank you for the example and reference. I appreciate your time.

Sign in to comment.

Categories

Products

Community Treasure Hunt

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

Start Hunting!