Converting signed byte to decimal

This is probably a very simple question, but I am stumped at the moment. I have forked an existing sketch and converted it into an Arduino library. The original sketch has the following relevant code:

struct {
   char stick_y;
} N64_status;

// These are 8 bit values centered at 0x80 (128)
for (i = 0; i < 8; i++) {
        N64_status.stick_y |= N64_raw_dump[24 + i] ? (0x80 >> i) : 0;
    }

Now, this works great. After all is said and done a value from +/-85 gets printed to the console depending on the direction of the joystick (up/down).

    Serial.print("Y joystick::");
    Serial.println(N64_status.stick_y, DEC);

Now for the question. I don’t want to print this value. Instead, I would like to store its decimal equivalent. When passing DEC to Serial.println, it provides the exact output that I need, however I don’t know println converts this. I have searched around for converting a single signed char into decimal but have hit a wall. Any help would be greatly appreciated.

Thanks!

What, exactly, do you mean by "convert to decimal"?
Do you want an ASCII character string that represents the decimal value? If so, use itoa().

Serial.println( x, HEX ) displays the value of x in HEX numbering system format, but it does not change the value of x at all. It remains the same integer value.

'char stick_y' is stored as a decimal value. Serial.print converts it to a text representation. So the decimal value -85 is printed as text with the characters '-', '8' and '5'.

Ah I see what's going on now. Yes you are all right. Once I read sterretjes response a few times it all made sense. I think I should figure out how to use the debugger before I move forward. Had I set a breakpoint to see the contents of N64_status.stick_y prior to the println this would be been an easy problem to solve. Thanks again!

N64_status.stick_y is stored as a binary value, which serial.println by default represents using ASCII characters for the decimal value.

Thanks jremington. I have verified you were correct. When the joystick is the in up position, N64_status.stick_y contains 01010101, which is 85. The tricky part is when it's negative. For example, with the joystick in the down position:

        Serial.println(controller.y, DEC);
        Serial.println(controller.y, BIN);

Output:
-84
11111111111111111111111110101100

My goal out of this whole process to to take the byte, and convert it to a +/- integer representation in base 10. For example, the input would be a char with a value of 01010101, the output would be an int with a value of 85.

I don't understand why you think there is a difference. 85 is the decimal representation of a number, which has binary representation 01010101.

Serial.print(), itoa(), sprintf() etc. can all produce human readable representations of binary numbers in many different number bases.

If you just need to know whether the joystick is up or down, isn't the sign (+/-) of the returned value sufficient?

rchapps:

        Serial.println(controller.y, DEC);

Serial.println(controller.y, BIN);




**Output:**
-84
11111111111111111111111110101100

A char can only contain 8 bits; so the output result of the serial.println is actually nonsense as it displays 32 bits. The correct result for a char is

10101100

You need to be able to ‘translate’ what you see to what it actually means. You can get the correct result using a so called cast

void setup() {
  char cVal1 = 85;
  char cVal2 = -85;

  Serial.begin(9600);
  Serial.print("cVal1 "); Serial.println((byte)cVal1, BIN);
  Serial.print("cVal2 "); Serial.println((byte)cVal2, BIN);

}

This code tells the compiler to treat cVal1 and cVal2 as bytes (unsigned char) and hence to ‘assume’ that those values need to be represented as positive numbers. If you want to display the text representation of bits in the character variable, this is the correct way to do it. It’s important to understand that cVal1 and cVal2 don’t change; you only tell the compiler how to treat them.

rchapps:
My goal out of this whole process to to take the byte, and convert it to a +/- integer representation in base 10. For example, the input would be a char with a value of 01010101, the output would be an int with a value of 85.

I think that you’re a little confused; what you want is a number, but you call it an int.

Computers don’t know about characters, character strings and so on; they only know about numbers. What those numbers represent depends on what you do with them. So your char is a number (that can range from -128 to +127) in this case and you can use it like that.

The below code will display all values that fit in a byte in memory. It will also demonstrate the difference between a char variable and byte variable when it comes to the decimal value.

The first loop uses a char variable. The first column displays the value in hex (0x00 … 0xFF; a cast was used to enforce this), the second column the value in decimal as is and the last column displays the character that is represented by the value of the variable (it displays a dot for values below 0x20).

The second loop uses a byte variable and does the same; note that no casts were required.

void setup() {
  char buffer[64];
  char charVariable = 0;
  byte byteVariable = 0;
  Serial.begin(9600);


  for (int cnt = 0; cnt < 256; cnt++)
  {
    sprintf(buffer, "0x%02X %4d %c ", (byte)charVariable, charVariable, (byte)charVariable < 0x20 ? '.' : charVariable);
    Serial.println(buffer);
    delay(50);
    charVariable++;
  }

  Serial.println("Send some character to continue");
  while(Serial.available() == 0);

  for (int cnt = 0; cnt < 256; cnt++)
  {
    sprintf(buffer, "0x%02X %4d %c ", byteVariable, byteVariable, byteVariable < 0x20 ? '.' : byteVariable);
    Serial.println(buffer);
    delay(50);
    byteVariable++;
  }


  //Serial.print("charVariable1 "); Serial.println((unsigned int)charVariable1, BIN);
  //Serial.print("charVariable2 "); Serial.println((unsigned int)charVariable2, BIN);

}