Decimal to hexadecimal - store in a String

Hello,

I need help with a function that converts a decimal integer (variable in length) to a Hexadecimal string.

I've seen a lot on the web, they just print things out. When I try to store them in a variable, It doesn't seem to work or doesn't get returned correctly (I end up seeing inverted question marks in between characters :-/)

Any help would be appreciated!

Thanks,
SN

You would do that in two steps:

  1. convert the decimal string to binary
  2. convert the binary value to a hex string

Do I assume correctly that your "decimal integer" is a string?

The decimal integer is an int.

When you store something to a variable it is stored in binary. All numbers and characters are stored in binary. Decimal, hex, text, etc. are all representations of binary data so that humans can read it.

Please show the data that you wish to store and explain what you want to do with the data.

Take a few minutes to read the forum guidelines and how to use this forum stickies.

Yes, I understand. I'll tell you my application.

I need to send large chunks of data through a RF transmitter. I send it as a String through the RF transmitter. Converting numbers to Hex, helps me reduce the number of characters I use to transmit the same info, as compared to decimal.

E.g. "100 101 102 103 104 200 201 202 255" is just "64 65 66 67 68 C8 C9 FF" in Hex. That's convenient to transmit, lesser data loss and all that.

Here's the code that is misbehaving! I think the problem lies in converting to String. Please help. This outputs random characters.

// 02 DEC TO HEXA CONVERT
void decToHexa (int decimalnum) {
  int quotient = 0; int remainder = 0;
  int j = 0;
  char hexadecimalnum [5];
  
  quotient  = decimalnum;

  while (quotient!=0) {
    remainder = quotient % 16;
    if (remainder < 10) {
      hexadecimalnum [j++] = 48 + remainder;
    } else {
      hexadecimalnum [j++] = 55 + remainder;
    }
    quotient  = quotient / 16;
  }

  char res[sizeof(hexadecimalnum)];
  Serial.print ("The value is :");
  // display integer into character
  int k = 0;
  for (int i=j; i >=0; i--) {
   
    Serial.print (hexadecimalnum[i]);
    res[k] = hexadecimalnum [i];
    k++;
  } Serial.print ("\n");
  
  for (int i=0; i<sizeof(res); i++) {
      Serial.print (res[i]);
  }
  // return res;
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
  int num = 254;
  decToHexa (num);
  
}

void loop() {
  // put your main code here, to run repeatedly:

}
  Serial.print ("The value is :");
  // display integer into character
  for (int i=j; i >=0; i--) {
    int k = 0;
    Serial.print (hexadecimalnum[i]);
    res[k] = hexadecimalnum [i];
    k++;
  } Serial.print ("\n");

This is really a strange bit of code. It starts out okay, but then you create a fresh variable k, which is used once in place of value 0, after which it is incremented, and then discarded. Perhaps it would be good to comment each line to explain what you are trying to do.

Use descriptive variable names, for example "temperature" instead of "t".

Do you understand that C strings are normally terminated with zeroes ("\0" in code)?

I corrected that mistake earlier, don't know why it didn't reflect. k=0; is before the for loop. Anyway, here's the code:

// 02 DEC TO HEXA CONVERT
void decToHexa (int decimalnum) {
  int quotient = 0; int remainder = 0;
  int j = 0;
  char hexadecimalnum [5];
 
  quotient  = decimalnum;

  while (quotient!=0) {
    remainder = quotient % 16;
    if (remainder < 10) {
      hexadecimalnum [j++] = 48 + remainder;
    } else {
      hexadecimalnum [j++] = 55 + remainder;
    }
    quotient  = quotient / 16;
  }

  char res[sizeof(hexadecimalnum)];
  Serial.print ("The value is :");
  // display integer into character
  int k = 0;
  for (int i=j; i >=0; i--) {
   
    Serial.print (hexadecimalnum[i]);
    res[k] = hexadecimalnum [i];
    k++;
  } Serial.print ("\n");
 
  for (int i=0; i<sizeof(res); i++) {
      Serial.print (res[i]);
  }
  // return res;
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
  int num = 254;
  decToHexa (num);
 
}

void loop() {
  // put your main code here, to run repeatedly:

}

Is this what you're looking for? It takes and integer and converts to text.

  char hexadecimalnum [5];
  sprintf(hexadecimalnum, "%d", num);
  Serial.println(hexadecimalnum);

Note that you are not using String (capital S) which is great. You're a so-called c-string which is better in the Arduino world.

I changed the "%d" to "%X". It works like a charm!

Thanks a lot! You've really helped me with that!

Best regards,
SN

Careful, %X doesn’t include leading zeroes.
You may prefer %02X
You can eliminate the spaces too if they’re always 2 char hex values.
A checksum might be desirable...

One last thing.. You can block the data and send it as binary byte values, rather than as ASCII hex numbers. Half the number of chars in this case.

subramanyamn:
I changed the "%d" to "%X". It works like a charm!

OOPS, overlooked that :frowning: Good that you found it.

An alternative to sprintf is itoa.

itoa is a non iso C function but is supported in avr-libc which is the standard c library for AVR-GCC compiler.

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#gaa571de9e773dde59b0550a5ca4bd2f00

char * itoa (int N, char *str, int base)
char hexadecimalnum [5];
itoa(num, hexadecimalnum, 16);
Serial.println(hexadecimalnum);