Difficulty with i2c Read Register. Not enough information in the doc
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
0 votes
So i am working with an I2C device and reading in 8 bit register data
The problem is the following. The doc does not allow for data to be read in a specific format.
The register is currently housing data in a 2,s complement format
When i read from the register its giving decimal answers.
This is a problem because i have no idea what conversion its doing in the background. It sure doesn't know that what its reading is 2s complement so I'm assuming the decimal number I'm getting back is wrong also.
How can i just read the register in pure binary?
There is nothing in the doc
Accepted Answer
Walter Roberson
on 24 Jan 2017
0 votes
If you are using arduino and read() of an i2cdev object, then the transfer always binary. As is always the case, by default MATLAB displays binary numbers in decimal . You can use dec2bin() to display it as binary.
I suspect that want you want is to pass 'int8' to the read() routine.
8 Comments
Robert
on 24 Jan 2017
Hello Walter
no I'm using the readRegister function to read the registers of a device that is connected to an arduino. The arduino is just acting as a data aquisition model for me and or a communication buffer to the hardware.
The data that is in the register is 2s complement So when the function converts it to decimal its incorrectly converting it because it thinks its an unsigned 8 bit binary number
How do i get it back into the proper format
Right now I'm doing the following and its not working
Im taking the decimal number it gives me and using
dec2bin(,8) so i get an 8 bit number back
Then I'm taking that binary number and sticking it in a 2s complement function i found online.. However its giving me the wrong answer
I don't know if its a bogus function i found or what? Here is the code for the function i found
function i = twoscomp2int(b)
% TWOSCOMP2INT(B) Convert a twos-complement binary number, B,
% represented as a row vector of zeros and ones, to an integer. Twoscomp2int
% operates on the rows of a matrix.
[m, n] = size(b);
i = -b(:,1).*2.^(n-1) + b(:,2:end)*transpose(2.^(n-2:-1:0));
Walter Roberson
on 24 Jan 2017
typecast(uint8(theValue), 'int8')
but better yet, just pass 'int8' as an option to readregister
Robert
on 24 Jan 2017
i did try the int8 int readRegister it still gave me decimal no idea why
i looked up the typecast function but I'm still unsure what its doing
are you saying to use typecast to go from 2s to decimal?
Walter Roberson
on 24 Jan 2017
If you need a bit-oriented output then you need to use dec2bin()
That typecast changes the interpretation of the binary value from unsigned 8 bit integer to signed 8 bit integer.
For example,
nu8 = uint8(bin2dec('10000001'))
dec2bin(nu8)
ns8 = typecast(nu8, 'int8')
You cannot use dec2bin() to display signed integers. If you have the Fixed Point Toolbox then you can use
fis8 = fi(ns8)
fis8.bin
and you will see that the binary has not changed even though the number is now interpreted as negative.
Robert
on 24 Jan 2017
ok well this is a pretty big problem then
If you say i can not use dec2bin to display signed integers then i don't know what to do about this because the data that is in the register is in 2s complement.
readRegister is going in the register and reading something that is in 2s complement and returning to me a decimal number.
So if i can't take that decimal number and put it in dec2bin to get it back to binary i don't know what to do. What clown wrote the readRegsiter function such that it auto converts to a unwinded decimal? Completely ridiculous
Why not write it so it gives us back the binary and let the programmer decide for himself how to interpret it.
this is a pretty big screw up Do you have any idea how to do one of two things?
Either get readRegsiter to give me the result in the original format as its actually stored in the register
or
when it gives me the decimal back, how to unconvert it back to the 2s complement form so I can interpret it correctly
Walter Roberson
on 24 Jan 2017
There is no electrical difference at all between a byte used to store -87 (decimal, 2's complement) or 169 (decimal, unsigned) or 10101001 (binary) or '©' (character). The difference is only in interpretation. readRegister is returning what really is in the register. The question is how you interpret it. If you want the signed byte interpretation then add the 'int8' option to readRegister. If you want to look at the binary that is stored in the result, then typecast() the result to uint8 and dec2bin()
vals = readRegister(c, 20, 'int8'); %register 20 of device c, returned as signed byte
valu = typecast(vals, 'uint8'); %does not change value, just interpretation
val_as_bitstring = dec2bin(valu, 8) %build one of the binary representations of that, this time as a string of '0' and '1'
val_as_bits = val_as_bitstring - '0' %build a different binary representation, this time as a vector of 0 and 1
What you would get in val_as_bitstring and val_as_bits are not the value itself: they would be ways of displaying the values in different forms.
Think of the number 10 (decimal). One of the ways of representing it is '10', the pair of characters. One of the ways of representing it is by writing the numeral 1 and then the numeral 0, which is the base 10 representation. The base 9 representation of the same number could be written as 11; the base 8 representation as 12; base 7 as 13; base 6 as 14; base 5 as 20; base 4 as 22; base 3 as 101; base 2 as 1010; base 1 as 1111111111 . Those are all representations that are useful for different purposes, but none of them is the number; the number is itself, a pure idea.
You might find it convenient, for checking purposes, to
dec2bin(typecast(vals, 'uint8'))
I promise you that this will show you a correct binary representation of the signed 8-bit byte. For example,
vals = int8(-87)
dec2bin(typecast(vals, 'uint8'))
This will return '10101001' . You can cross-check that this is correct by performing 2's complement: negate each bit individually, and add 1 to the last bit, giving '01010111' . Now bin2dec('01010111') and you will get 87, so '10101001' really is a 2's complement representation for the negative of 87. The binary stream 10101001 is how -87 is stored in a signed byte. That also happens to be the way that 169 is stored in an unsigned byte. This is not a contradiction or an error: this is a matter of how the actual binary is to be interpreted.
Fawwaz Hosein
on 7 Apr 2020
Thank you Walter for such a lengthy response. However, consider the case when the register returns the 2's complement value as '00110000'. Now, reading this value as a signed value is correct. However even changing the type to unsigned then converting using dec2bin could still end up in error. Since with 2's comp we essentially are looking for the MSB bit (i.e. the sign bit). Referring to the previous 8 bit number, we would be unsure if the MSB is a 0 or a 1. Therefore performing dec2bin would automatically make the assumption that the MSB is 1 which would be wrong.
Walter Roberson
on 7 Apr 2020
Understanding the I2C Bus
Data is transferred Most Significant Bit (MSB) first.
As the bit order for I2C is fixed, there is no possibility that the bit order for any given device should be the other way around. This is not a negotiable property of the device.
More Answers (0)
Categories
Find more on MATLAB in Help Center and File Exchange
Tags
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)