How Do I Convert Decimal To Hexadecimal? - Arduino Forum

How do I convert decimal to hexadecimal? Projects Programming December 29, 2017, 10:23pm 1

Hello everyone,

How do I convert a decimal to a hexadecimal in code? I'm making an RGB color picker and I want to display the RGB value and the hex value of the color.

December 29, 2017, 10:35pm 2

Serial.print(15, HEX); will print F

December 29, 2017, 10:40pm 3

Why does it matter? The computer doesn't care about binary, octal, decimal or hexadecimal

December 29, 2017, 11:52pm 4

This is a very old problem, for which many new people don't know the answer.

Hexadecimal is a base 16 number system.

So when you divide a decimal number by 16, the remainder is one hexadecimal digit.

Then translate the remained into a character.

remainder of 0 goes into the character "0" ... the remainder of 15 goes into the character "F". Take the quotient of the division, and preform the same process on the remainder. So people write a recursive function to do this. or you can make it a function that returns the quotient, and check for a zero value in a while loop.

Hope this helps

December 30, 2017, 12:36am 5

just_a_guy: This is a very old problem, for which many new people don't know the answer.

Hexadecimal is a base 16 number system.

So when you divide a decimal number by 16, the remainder is one hexadecimal digit.

Then translate the remained into a character.

remainder of 0 goes into the character "0" ... the remainder of 15 goes into the character "F". Take the quotient of the division, and preform the same process on the remainder. So people write a recursive function to do this. or you can make it a function that returns the quotient, and check for a zero value in a while loop.

Hope this helps

That’s the theory on a piece of paper...

But no one (well may be you do?) does it like this in a typical computer because division and modulo are costly operations...

In practice data in your typical computer is stored in binary (base 2 - with 0 and 1) and accessed in bytes. As 24 = 16, if you read 4 bits in one go you can have an HEX digit right there (base 16) —> So we would just iterate through the content of those bytes - first the 4 High bits and then 4 Low bits (with masking/shifting) - and use that to build the HEX representation

January 1, 2018, 3:07pm 6

decimal to hexadecimal? - google for- decimal to hexadecimal online converter

January 1, 2018, 6:01pm 7

cwduffy01: ...I want to display the RGB value and the hex value of the color.

you can build a string using C Format Specifiers

void setup() { Serial.begin(9600); uint8_t red = 255; uint8_t green = 125; uint8_t blue = 0; char colorBuffer[24]; snprintf(colorBuffer, sizeof(colorBuffer), "R:0x%02X G:0x%02X B:0x%02X", red, green, blue); Serial.println(colorBuffer); } void loop() { } January 1, 2018, 6:49pm 8

Here's a sample program that uses just_a_guy's suggestion of recursive function:

// Recursive function that prints a number out in HexaDecimal ASCII void printHex(unsigned int numberToPrint) {   if (numberToPrint >= 16)     printHex(numberToPrint / 16);   Serial.print("0123456789ABCDEF"[numberToPrint % 16]); } void setup() {   Serial.begin(9600);   printHex(1234);        // Output => 4D2   Serial.println();   printHex(0x1234);      // Output => 1234   Serial.println(); } void loop() { }

J-M-L is correct, that arbitrary division and mod operations are costly, however, dividing by 16 and mod 16 can be done with more efficient bit shifts and logical AND instructions respectively. Luckily, the compiler is smart enough to recognize this and created impressively efficient assembly code.

January 1, 2018, 7:29pm 9 void byte_to_str(char* buff, uint8_t val) {  // convert an 8-bit byte to a string of 2 hexadecimal characters   buff[0] = nibble_to_hex(val >> 4);   buff[1] = nibble_to_hex(val); } char nibble_to_hex(uint8_t nibble) {  // convert a 4-bit nibble to a hexadecimal character   nibble &= 0xF;   return nibble > 9 ? nibble - 10 + 'A' : nibble + '0'; }

Usage:

  uint8_t red = 16; // 16 = 0x10   uint8_t green = 0; // 0 = 0x00   uint8_t blue = 255; // 255 = 0xFF // as a char array   char rgbTxt[7];   rgbTxt[0] = '#';   byte_to_str(&rgbTxt[1], red);   byte_to_str(&rgbTxt[3], green);   byte_to_str(&rgbTxt[5], blue);   Serial.write(rgbTxt, 7); // prints '#1000FF' // as a null-terminated char array (string)   char rgbTxt[8];   rgbTxt[0] = '#';   byte_to_str(&rgbTxt[1], red);   byte_to_str(&rgbTxt[3], green);   byte_to_str(&rgbTxt[5], blue);   rgbTxt[7] = '\0';   Serial.print(rgbTxt); // prints '#1000FF'

Alternatively (uses much more memory):

  char rgbTxt[8];   sprintf(rgbTxt, "#%02X%02X%02X", red, green, blue);   Serial.write(rgbTxt, 7); // or   Serial.print(rgbTxt);

Or (not supported on AVR):

Serial.printf("#%02X%02X%02X", red, green, blue);

Pieter

January 1, 2018, 7:31pm 10

I'm curious - how does   return nibble > 9 ? nibble - 10 + 'A' : nibble + '0';compare to return "0123456789ABCDEF"[nibble]; for code size?

January 1, 2018, 7:56pm 11

Very interesting ... The one with the string indexing uses 16 bytes of (static) RAM more than the one with the ternary operator. What surprises me is that it uses 14 bytes of flash more.

My intuition says that the first one should require more operations.

Which one would be fastest? The first one does have branching ...

char nibble_to_hex(uint8_t nibble) {  // convert a 4-bit nibble to a hexadecimal character (31684 B)   nibble &= 0xF;   return nibble > 9 ? nibble - 10 + 'A' : nibble + '0';  // 488 B flash, 12 B RAM   // return "0123456789ABCDEF"[nibble];                  // 502 B flash, 28 B RAM } volatile uint8_t value = 12; volatile char hex; void setup() {   hex = nibble_to_hex(value); } void loop() {} January 1, 2018, 8:00pm 12

I'm fairly sure the string could remain in flash with a PSTR.

January 2, 2018, 6:45pm 13

@PieterP The way I understand it, any initializers you use for variables in RAM have to be initialized in Flash and copied there, so yeah the 17 bytes have to be there in Flash as well.

@AWOL I tried to figure out how to pull the data straight out of flash without declaring it in RAM first. Turns out it's not that simple. Not like simply adding an F() macro. :slight_smile: I got it to work like this:

const char hexCharArray[] PROGMEM = "0123456789ABCDEF"; void printHex(unsigned int numberToPrint) {   if (numberToPrint >= 16)     printHex(numberToPrint / 16);   Serial.print(pgm_read_byte(hexCharArray + numberToPrint % 16)); }

However, it uses 1740 bytes of Flash, and 188 bytes of RAM.

This one uses 1550 of Flash, and 204 of RAM:

const char hexCharArray[] = "0123456789ABCDEF"; void printHex(unsigned int numberToPrint) {   if (numberToPrint >= 16)     printHex(numberToPrint / 16);   Serial.print(hexCharArray[numberToPrint % 16]); }

So yeah, I saved 16 bytes of RAM, at the expense of 180 bytes of Flash?!?

I looked at the assembly code it produced, and it generates in-line code to pull the data directly from flash. It doesn't take any 180 bytes to do that. So I'm guessing that using pgm_read_byte() pulls in code from a library or object file that doesn't show up in my code anywhere. And probably never gets used.

I tried to find the source code where it does that stuff, and it's hidden pretty well. Of course doing a grep "F" * is useless. And PSTR doesn't seem to have any references in the documentation.

Still looking...

January 2, 2018, 7:24pm 14

Nervermind. I found it. Somehow typecasting it makes it work. Flash 1554, RAM 188:

const char hexCharArray[] PROGMEM = "0123456789ABCDEF"; void printHex(unsigned int numberToPrint) {   if (numberToPrint >= 16)     printHex(numberToPrint / 16);   Serial.print((char)pgm_read_byte(hexCharArray + numberToPrint % 16)); }
Topic Replies Views Activity
RGB to HEX Programming 40 23981 May 5, 2021
Decimal to hexadecimal - store in a String Programming 13 10888 May 6, 2021
Storing a DEC value as HEX Programming 8 1900 May 5, 2021
como pasar un string en hexadecimal a decimal. Software 7 6838 May 7, 2021
Getting byte values to appear as decimal. Programming 2 3888 May 5, 2021
Unfortunately, your browser is unsupported. Please switch to a supported browser to view rich content, log in and reply.

Tag » Arduino Convert Decimal A Hexadecimal