[Solved] Hex char * without 0x to byte ? (rgb MySensors message.data)

Hi,

I´m struggeling with a "simple" problem for hours now.

I have an incoming const char * (message.data), f.e. F9BF69, or 020581, whatever. Want to translate it to an decimal red green and blue value in the end. Problem seems to be the missing 0x, so I am not able to just cast it to an int.

Idea was now to create single chars for 0, x and two chars of my 6er const *, some examples.:

              char t1 = message.data[0];
 Serial.print("t1 = ");
 Serial.println(t1);
 char t2 = message.data[1];
 Serial.print("t2 = ");
 Serial.println(t2);
 char pre1 = '0';
 char pre2 = 'x';
 char a1[] = { pre1 + pre2 + t1 + t2 };
 char a2 =  pre1 + pre2 + t1 + t2 ;
 String a3 = "";
 a3 += pre1 + pre2;

None of this worked. I am getting strange numbers when casting to String (maybe ASCII ?), and have not found a way to get my hex out of there. Also played with strdup and then atoi or strtoi, or first cast to String - no solution.

Any ideas?

So you are receiving 'F9BF69' as a text? Or is it binary data?

int asciiHexToInt(char c) {
  int x = 0;
  if (c >= "0" && c <= "9") x += c - "0";
  else if (c >= "A" && c <= "F") x += c - "A";
  return x;
}

The only problem here is if 0x or 0X is sent, it will be evaluated as an INT but it should return 0 for each character, so it ultimately should work on the entire string...

Perehama:

int asciiHexToInt(char c) {

int x = 0;
  if (c >= "0" && c <= "9") x += c - "0";
  else if (c >= "A" && c <= "F") x += c - "A";
  return x;
}



The only problem here is if 0x or 0X is sent, it will be evaluated as an INT but it should return 0 for each character, so it ultimately should work on the entire string...

Perfect point to start from, thank you very much :smiley:

Much better then first put chars together.

As it is RGB, i had to always put two of em together, if someone else has a similar problem (this is only for 3x2 hex values :wink: ):

for (byte aP = 0; aP < 6;)
			{
				byte x = 0;
				for (byte r = 0; r < 2; ++r)
				{
					byte mult = 0;
					switch (message.data[aP]) {
					case 'A':
						mult = 10;
						break;
					case 'B':
						mult = 11;
						break;
					case 'C':
						mult = 12;
						break;
					case 'D':
						mult = 13;
						break;
					case 'E':
						mult = 14;
						break;
					case 'F':
						mult = 15;
						break;
					default:
						mult = message.data[aP] - '0';
						break;
					}
					if (r == 0) x = mult * 16;
					else x += mult;
					++aP;
				}
				switch (aP)
				{
				case 2:
					redNext = x;
					break;
				case 4:
					greenNext = x;
					break;
				case 6:
					blueNext = x;
					break;
				}
			}

There is a much easier way to combine two hex values into one byte as each represents a nibble.

x += highNibble << 4;
x += lowNibble;

If we modify my earlier posted function (and fix the double quotes ;-)), we get:

byte asciiHexPairToByte(char cHigh, char cLow) {
  byte x = 0;
  if (cHigh >= '0' && cHigh <= '9') x += cHigh - '0';
  else if (cHigh >= 'A' && cHigh <= 'F') x += cHigh - 'A';
  x << 4;
  if (cLow >= '0' && cLow <= '9') x += cLow - '0';
  else if (cLow >= 'A' && cLow <= 'F') x += cLow - 'A';
  return x;
}

Thanks again

After few minor changes it works like a charm ;D

for (byte aP = 0; aP < 6;)
		{
		byte x = 0;
		if (message.data[aP] >= '0' && message.data[aP] <= '9') x += message.data[aP] - '0';
		else if (message.data[aP] >= 'A' && message.data[aP] <= 'F') x += message.data[aP] - '7';
		x = x << 4;
		++aP;
		if (message.data[aP] >= '0' && message.data[aP] <= '9') x += message.data[aP] - '0';
		else if (message.data[aP] >= 'A' && message.data[aP] <= 'F') x += message.data[aP] - '7';
		++aP;

		switch (aP) {
		case 2:
			redNext = x;
			break;
		case 4:
			greenNext = x;
			break;
		case 6:
			blueNext = x;
			break;
		}
	        }