0

I'm sending in a hex representation of a byte through the serial port and I needed to convert it to a byte to use in my application. I've approached it several different ways and it looks like there's got to be an easier way to approach it than the way I have been (and I haven't yet found anything online that resolves this issue). I'm guessing there's probably a simple function that does what I want it to do without 3 or 4 different conversions.

Does anyone have any suggestions on how to approach this?

Essentially, I'm trying to take a string (inString) with value "CE" and store the equivalent in byte form (0xCE or 206) into outByte. Below is what I'm currently working with:

Original Code:

String inString = “CE”
Byte outByte;
outByte = inString.toInt();
printData("outByte: " + String(outByte),serialchan);

Output:

outByte: 0

Additional approaches:

String inString = “CE”
Byte outByte;

char tempchar[2];
String tempstring;
inString.toCharArray(tempchar, 4); // Works with 4, not with 2 for whatever reason
printData("inString: " + String(inString),serialchan);
printData("inString hex: " + String(tempchar),serialchan);

tempstring = "0x" + String(inString);
printData("inString in string hex: " + String(tempstring),serialchan);
outByte = (byte)tempstring.toInt();
printData("outByte: " + String(outByte),serialchan);

Output:

outByte: 0                                                        
inString: CE                                                   
inString hex: CE                                                
inString in string hex: 0xCE                                     
outByte: 0

I'm expecting outByte to read 206 (I'll convert it to a hex string later, I'm guessing that's pretty straight forward). Like I said, I think I'm close . . . but there just seems like there should be a simple one or two line solution to this. If you have any suggestions, please let me know. Thanks!

10
  • 2
    This doesn't look like C at all. Commented Mar 29, 2023 at 17:10
  • 1
    You can convert a C string in various number bases to an integer using strtol. For example long val = strtol(inString, NULL, 16);. Or you can use sscanf. Commented Mar 29, 2023 at 17:12
  • 1
    You could copy the Arduino String to a C-style buffer first with its getBytes() method? Commented Mar 29, 2023 at 17:35
  • 1
    Don't use such tiny strings. The one you supplied is too small, and you told the function it is twice is actual size. Commented Mar 29, 2023 at 17:46
  • 1
    Sorry, C strings have a nul terminator, 2 bytes is too short. Use a buffer size 4 and pass the actual size of the buffer available. If it is length 4 then you pass 4 to the getBytes. Commented Mar 29, 2023 at 17:49

2 Answers 2

2

If you don't mind about validation (i.e. input string is always valid hexadecimal ASCII string) you can use this case-insensitive almost branchless snippet:

static unsigned char nibble(char c)
{
    return c % 16 + 9*(c >> 6);
}

unsigned int hex2num(const char *s)
{
    unsigned int r = 0;
    while (*s)
        r = (r << 4) | nibble(*s++);
    return r;
}
Sign up to request clarification or add additional context in comments.

Comments

1
int convertDigit(char a) {
    if (a >= '0' && a <= '9') return a - '0';
    if (a >= 'A' && a <= 'F') return a + 10 - 'A';
    assert(0 && "not valid");
}

int HexToByte(char *string) {
    unsigned int length = strlen(string);
    int value = 0;
    for (int i = 0; i < length; ++i) {
        value += convert(string[i]) * pow(16, length - i - 1);
    }
    return value;
}

I wrote this relay fast but should do what you need. Pay attention that require math for the pow function but that can be easily implemented.

[EDIT] thanks to @dimich

int convertDigit(char a) {
    if (a >= '0' && a <= '9') return a - '0';
    if (a >= 'A' && a <= 'F') return a + 10 - 'A';
    assert(0 && "not valid");
}

int HexToByte(char *str) {
    int value = 0;
    while (*str) value = (value << 4) | convert(*str++);
    return value;
}

2 Comments

I essentially ended up writing something along these lines based on an example I saw. I would've thought there would be an easier way to approach it but I checked everywhere, no luck. Thanks for your help!
while (*str) value = (value << 4) | convert(*str++). No "pow function" needed.

Your Answer

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.