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);

}
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. :)

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.