0

I've seen a couple old posts that had a similar context but the answers were code snippets, not explanatory. And I can't even get the code offered in those answers to compile.

I apologize in advance if this is poorly formatted or explained, I am new to C++ and I avoid asking questions on forums at all costs but this has become a real thorn in my side.

I am using C++ to access the memory register of an accelerometer. This register contains 8 bits of data in the form of twos complement.

The accelerometer is set to have a range of +/- 2 g's, meaning (see section 1.5 of reference manual on page 10)

My goal is to take this twos complement data and save it to a text file as signed base-10 data.

Relevant code below:

        while(1)
    {
            int d = 0;
            d= wiringPiI2CReadReg8(fd, DATA_X_H);
            d = (int8_t)d;
            d = d * EIGHTBITCONV;
            std::cout << d << std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

I've tested the program by hard coding "d" as 01111111 (127) and the program returns "73". But hard coding "d" as 10000001 (-127) and the program returns the correct "-127".

So the program only functions properly when dealing with negative numbers.

Is this happening because when casting the float "d" to an 8bit integer it truncates the leading zero for positive numbers? How would I fix this?


Link to datasheet: https://www.mouser.com/datasheet/2/348/KX132-1211-Technical-Reference-Manual-Rev-1.0-1652679.pdf

2
  • -(~(int8_t)d +1) is some screwed up attempt to do -(-d). You shouldn't need that at all. At most cast the result of wiringPiI2CReadReg8 to int8_t if it doesn't do that already. Commented May 14, 2022 at 22:14
  • 1. What do you mean by "signed base-10 data"? (Do you mean text?). 2. You could update the test values with binary numbers (or decimal numbers representable in 8 bits: -128...127). Commented May 14, 2022 at 22:39

2 Answers 2

2
  1. You do not need to convert from 2's complement to "signed integer", because 2's complement is signed integer.

  2. You are only reading 8 bits, but int (the return type of wiringPiI2CReadReg8) has more. So you need a sign-extend conversion. Something like:

int result = (int)(signed char)wiringPiI2CReadReg8(fd, DATA_X_H);

The (int) conversion is implicit and can be omitted. And in your case you are converting to a float (The conversion is again implicit). So:

d = (signed char)wiringPiI2CReadReg8(fd, DATA_X_H);

Actually your solution (negating twice) would work as well. More explicitly it could be written like this (since 1 is int):

 d = -((int)(~(int8_t)d) + 1);

But this is just unnecessary work. It could be simplified to be:

d = -(-(int8_t)d);

and now it is obviously simplifies into:

d = (int8_t)d;

same as what I wrote before.

Sign up to request clarification or add additional context in comments.

11 Comments

I ran the following code based off of your input: using name space std; int main() { int d = 11111111; int result = (signed char)d; cout << result << endl; } ___ The console returned -57. Am I implementing what you suggested correctly?
d = 0b1111'1111; - base 2, not base 10!
You do not have to use binary, you could set d to 255 for example. But decimal 11111111 would be out of range. So only last 8 bits of 0b101010011000101011000111 would be stored. Which is harded to reason about.
I got this code to run by changing it to 0b1111'1111 but I'm struggling to implement your original suggestion. I have changed the relevant line to: d = (signed char)wiringPiI2CReadReg8(fd,DATA_X_H); But now when I output d I get integers that are outside the range of values the accelerometer is designed to measure.
1. What integers do you get? 2. Can you link a datasheet for the accelerometer?
|
1

Ok so I think a lot of my confusion came from the fact that I was trying hard code values into my program without proper knowledge of how to do so.

If I were to do hard coding as a method to test the logic, I should have specified that the values of "d" were binary.

So it looks like my original code, while extremely sloppy, was functioning properly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.