Convert HEX string from device to number value

Pretty new to Arduino.... so please be gentle... I'm also A Pascal guy... So double whammy...

Anyways...

Working with a serial device.

Send my request... get back my response.. Simple part done and works.

I get back this value as an example which is stored in a String variable.

7C0A008F46BF

I strip 7C0A as not needed.

Then what ever is left I need to convert to a number value, so in this case

008F46B would be 9389759

I thought I could use strtol call, but couldn't get that to quite work out.
Probably just not understanding how to use it and String vs char but doing searches
I keep finding similar questions and 100 answers of different types but I seem to not
be able to weasel out the good from the bad answers :frowning:

See if this works for you:

void setup() {
  char buffer[] = "7C0A008F46BF";
  long value;

  Serial.begin(9600);

  value = strtol(&buffer[4], (char **) '\0', 16);
  Serial.print(value, DEC);
}

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

}

The code assumes that the first 4 characters are always thrown away.

I get back this value as an example which is stored in a String variable.

Store it in a null terminated array of chars (aka a string) instead and then you can use the many str* functions with it as illustrated by Jack.

Thanks that got me further.....

Now I am to my 2nd part of this ....

I got to a point now where I do multiple calls to build a char buffer of

324731574835354B393139313230313934

I now need to convert this to text

which converted is

2G1WH55K919120194

Once I have that figured out, I think it's pretty much smooth sailing from here.

As its either converting from HEX to # value or HEX to String text ....

Came up with this… seems to work out.

Doesn’t qualify yet that the string has an even length… but it worked.

String HEX2String(String str){
char buffer[3];
int x;
String bStr;
bStr = “”;
x = 0;
for (x = 0; x < str.length(); x++) {
buffer[1]=str;
buffer[2]=str[x+1];
buffer[3]=’\0’;
bStr = bStr + char(strtol(&buffer[1], (char **) ‘\0’,16));
x++; // inc by 2
}
return bStr;
}

But if anyone has a better/faster way please let me know :slight_smile:

  1. Need code tags. The forum software mangled part of the code posted without them making part of it unreadable.

  2. Don’t use the String class. That’s what is giving you trouble trying to convert things. Use char arrays from the get-go so you can use the str* functions to parse out what you need. Not to mention the code bloat and memory management issues that the String class brings along. The word String with a capital S shouldn’t appear anywhere in your code once you’ve got it right.

  3. Instead of just a snippet where we have to guess how to fit a suggestion with the rest of your code, post the whole thing if you really want good help.

Agree with Delta-G…String class is wasteful. Try this:

char input[] = "324731574835354B393139313230313934";

void setup() {
  char temp[3];
  char output[20];
  int i;
  int index;

  Serial.begin(9600);

  for (i = 0, index = 0; i < sizeof(input); i += 2, index++) {
    strncpy(temp, &input[i], 2);            // Grab 2 chars at a time
    temp[2] = '\0';                         // Treat it as a string
    output[index] = (char) convert(temp);   // Convert to ASCII
  }
  output[index - 1] = '\0';                 // Terminate string...
  Serial.println(output);
}

int convert(char in[])
{
  int tens;
  int digits;
    
  if (!isxdigit(in[0]) || !isxdigit(in[1]))   // Valid hex digit character?
    return -1;

  in[0] = toupper(in[0]);   // Use upper case
  in[1] = toupper(in[1]);
  
  tens = in[0] >= 'A' ? (in[0] - 'A' + 10) : in[0] - '0';
  digits = in[1] >= 'A' ? (in[1] - 'A' + 10) : in[1] - '0';
  return tens * 16 + digits;
}

void loop() {

}

Take the time to walk through the code to understand what it does.

Meh. Do it the old-fashioned way. Oldschool is the best school.

char input[] = "324731574835354B393139313230313934";

char output[sizeof(input)/2+1];

void setup() {
  foo(input, output);

  // blah blah blah, print the result
}

/*
  in must contain an even number of hex digits, uppercase, terminated by '\0'.
  out must be big enough to hold the result and a \0 terminator

  if either of these conditions does not hold, very bad things may happen.
*/

void foo(char *in, char *out) {
  while(*in) {
    *out++ = 
      ((in[0] - (in[0]>='A'?'A'-10:'0')) << 4) // high nybble
     |
      ((in[1] - (in[1]>='A'?'A'-10:'0')) ) ; // low nybble

    in += 2;
  }
  *out = '\0';
}