Converting HEX values into dBm.

Hello!

I want to convert hexadecimals such as FFCG to -49 (decimal from signed 2's complement) in Arduino.

The HEX values I want to convert are RSSI signals so I want to get their dBm value. I've tried using

strtol(), but can't seem to get the result I want. Any suggestions?

Thanks!

FFCG

?

RSSI is normally reported in dBm.

Some devices need calculations to be done on what is read out from RSSI registers, the calculations depend on the device and will be in its datasheet.

There is no concept of a standard conversion of HEX values into dBm.

I probably didn't word it right.

Take FFC4. In decimal it is converted to: 65476, I want it to be read as -60, which is the decimal from signed 2's complement.

I could not find the mentioned by you formula in the device's datasheet. I am taking the RSSI from a Bluetooth Module HC-05 which is connected to an Arduino Nano. Sorry if I am a bit unclear, electronics are not my field of expertise.

if the variable your place FFC4 into is a uint16_t (unsigned integer on arduino UNOs and similar) then yes, it is 65476
if you place the same hex number into an int16_t (signed int on arduino UNOs) then the value is -60.

void setup () {
  uint16_t unsigned_val = 0xFFC4;
  int16_t signed_val = 0xFFC4;

  Serial.begin(9600);

  Serial.println(unsigned_val, DEC);
  Serial.println(signed_val, DEC);
}

void loop() {
  
}

So when you're reading the registers, place the result into an int variable and you're there

If I understand the HC-05, these hex numbers arrive over the serial connection as part of a longer status message, so are really text strings like "FFC4" or "FFCG".

So I think the OP is trying to convert a text representation of a hexadecimal number to a numeric value.

void setup () {
  char instring[5] = "FFC4";
  //uint16_t unsigned_val = 0xFFC4;
  //int16_t signed_val = 0xFFC4;
  uint16_t unsigned_val;
  int16_t signed_val;

  Serial.begin(9600);

  signed_val = strtoul( instring, NULL, 16 );
  unsigned_val = strtoul( instring, NULL, 16 );

  Serial.println(unsigned_val, DEC);
  Serial.println(signed_val, DEC);
}

void loop() {
 
}

GypsumFantastic:
If I understand the HC-05, these hex numbers arrive over the serial connection as part of a longer status message, so are really text strings like "FFC4" or "FFCG".

So I think the OP is trying to convert a text representation of a hexadecimal number to a numeric value.

Of course, if he's getting a value like FFCG, then we're talking base 17 (at least). In which case both numbers are positive anyway, so two's compliment does not apply.

Determining the value, on the other hand ... :o

  signed_val = strtoul( instring, NULL, 16 );

Wouldn't it be better to use strtol?

  signed_val = strtol(instring, nullptr, 16);

Whandall:

  signed_val = strtoul( instring, NULL, 16 );

Wouldn't it be better to use strtol?

  signed_val = strtol(instring, nullptr, 16);

typo on my part. (loong day)

However, it does not really matter. The top two bytes are getting tossed anyways.
strtol and strtoul will both return the same thing when you give it a two byte hex number, no matter what the size. (Unless it's been a longer day than I though and I'm totally wrong.)

You're right though, it is better practice.

It is the data type and not the function type that determines the sign of the return value?

void setup ()
{
  Serial.begin(9600);
  char instring[5] = "FFC4";
  
  Serial.println((int)strtoul( instring, NULL, 16 ));                  //shows: -60
  Serial.println((unsigned int)strtoul( instring, NULL, 16 ));    //shows: 65476

  Serial.println((int)strtol( instring, NULL, 16 ));                    //shows: - 60
  Serial.println((unsigned int)strtol( instring, NULL, 16 ));      //shows: 65476
}

void loop()
{

}

GolamMostafa:
It is the data type and not the function type that determines the sign of the return value?

void setup ()

{
 Serial.begin(9600);
 char instring[5] = "FFC4";
 
 Serial.println((int)strtoul( instring, NULL, 16 ));                  //shows: -60
 Serial.println((unsigned int)strtoul( instring, NULL, 16 ));    //shows: 65476

Serial.println((int)strtol( instring, NULL, 16 ));                    //shows: - 60
 Serial.println((unsigned int)strtol( instring, NULL, 16 ));      //shows: 65476
}

void loop()
{

}

In this case It is the data type.

darrob:

void setup () {

char instring[5] = "FFC4";
  //uint16_t unsigned_val = 0xFFC4;
  //int16_t signed_val = 0xFFC4;
  uint16_t unsigned_val;
  int16_t signed_val;

Serial.begin(9600);

signed_val = strtoul( instring, NULL, 16 );
  unsigned_val = strtoul( instring, NULL, 16 );

Serial.println(unsigned_val, DEC);
  Serial.println(signed_val, DEC);
}

void loop() {

}

Thanks, that was exactly what I needed!