1

I have a program where the Arduino receives hex Strings that represent a RGBW color (similar to css for example). My goal is to create that color by using pwm, so I need to convert that one hex string into four integer values between 0..255 to use for the pwm. Whats the best/easiest way to do this?

Example:

void incomingMessage(const MyMessage &message) {
 // h = hex value
 // message = e.g. (h) #112233AB
 redval = ?; // h11 => 17
 greenval = ?; // h22 => 34
 blueval = ?; // h33 = 51
 whiteval = ?; //AB = 171
 analogWrite(RED_PIN, redval); 
 analogWrite(GREEN_PIN, greenval);
 analogWrite(BLUE_PIN, blueval);
 analogWrite(WHITE_PIN, whiteval);
}
asked Sep 30, 2015 at 17:01

2 Answers 2

1

I don't like using the String class because it can cause memory fragmentation. This would do it by just using C-style strings:

byte fromhex (const char * str)
 {
 char c = str [0] - '0';
 if (c > 9)
 c -= 7;
 int result = c;
 c = str [1] - '0';
 if (c > 9)
 c -= 7;
 return (result << 4) | c;
 }
void setup ()
 {
 Serial.begin (115200);
 Serial.println ();
 const char * test = "#112233AB";
 byte redval = fromhex (& test [1]);
 byte greenval = fromhex (& test [3]);
 byte blueval = fromhex (& test [5]);
 byte whiteval = fromhex (& test [7]);
 Serial.println ((int) redval);
 Serial.println ((int) greenval);
 Serial.println ((int) blueval);
 Serial.println ((int) whiteval);
 } // end of setup
void loop ()
 {
 // whatever 
 } // end of loop

Output:

17
34
51
171

That does not do any validation (that the string is indeed 9 characters long, and contain hex characters) but I'll leave that for you to do. :)

answered Sep 30, 2015 at 23:34
0

So you basically want to convert a pair of hexadecimal digits into a numeric value. You also want to extract those values from a string.

The latter can be done using the String.charAt() method. That allows you to extract individual characters from your string.

Then you need to convert those into a number. There's a number of ways that could be done.

strtol()

The strtol() function takes three parameters - the first is a C string (NULL-terminated char array) which contains the number you want to convert, the second you can ignore, and the third is the base to convert from. So you could use something like:

char temp[3] = { char1, char2, NULL };
int val = strtol(temp, NULL, 16);

Discrete functions

It's simple enough to write a function that converts a single hex digit into a value 0-15:

unsigned char h2d(unsigned char hex)
{
 if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case
 return(hex & 0xf);
}

It's then simple enough to use that to make a function that takes two hex digits and converts them into a number:

unsigned char h2d2(unsigned char h1, unsigned char h2)
{
 return (h2d(h1)<<4) | h2d(h2);
}

There's as many ways of doing it as there are of skinning a cat (as the saying goes). Every way has benefits and drawbacks though. Of the two I have shown, to compare them:

  • The first is "safer" as it has more error checking and can cope with other things besides hex values
  • The second results in much smaller code but results with values other than hex digits are undefined.
answered Sep 30, 2015 at 17:31

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.