1

I have to handle a String coming in over UART containing a bunch of information, part of it is a MAC-address that I get by using String.substring(a, b) returning a 12-char String representing a mac-address "B8C9A45BA770" <- (just an example).

I need the format of the mac-address to be a uint8_t array like so { 0xB8, 0xC9, 0xA4, 0x5B, 0xA7, 0x70 }.

So I need a function to convert a String to a uint8_t*. Sadly I have no clue how to convert this. There has so be an easy way right? its "C8" to 0xC8 and so forth...

Any ideas on this?

3
  • You can use sscanf Commented Jul 26, 2023 at 17:18
  • It would be easier to see you confusion if you actually showed some code. Commented Jul 27, 2023 at 1:48
  • Welcome to SE/Arduino! Please take the tour to learn how this site works, and read "How to Ask". You are supposed to do a good part of research on your own. So please edit your question and add what your research revealed, and why it did not help you. Hint: a quick web search on "c++ convert string to integer" give a lot of good hits... Commented Jul 27, 2023 at 6:48

1 Answer 1

2

Personally I'd go with a basic implementation such as this one.

const uint8_t MAC_length = 6;
uint8_t* MAC_buffer[6];

uint8_t fromHexChar(char c)
{
    uint8_t result = 0
    if ((c >= '0') && (c <= '9'))
        result = c - '0';
    else if ((c >= 'A') && (c <= 'F'))
        result = 10 + c - 'A';
    else if ((c >= 'a') && (c <= 'f'))
        result = 10 + c - 'a';
    return result
}

uint8_t* toMAC(String s)
{
    for (uint8_t i = 0; i < MAC_length; i++)
    {
        MAC_buffer[i] = (fromHexChar(s.charAt(2*i)) << 4) | fromHexChar(s.charAt(2*i + 1));
    }
    return MAC_buffer;
}

Probably it can be optimized, but this is such a simple job and to be used so rarely that I think this is enough.

Important: I did not test this code, so there may be bugs inside.

If you need to start from an arbitrary point in the String instead of at the beginning, you simply have to modify it this way:

uint8_t* toMAC(String s, uint8_t startIdx)
...
        MAC_buffer[i] = fromHexChar(s.charAt(2*i + startIdx)) << 4 | fromHexChar(s.charAt(2*i + startIdx + 1));

Note for future me: I checked both on a simulator and in the code, and charAt is safe to use even when the index is outside the string boundaries (it simply returns 0).

10
  • Many thanks! Hopefully I can try it out within my code today, if not it's going to be next week :) Commented Jul 27, 2023 at 8:31
  • I have a question though: Why are you using globals in this case? Wouldn't it be better to have a pure function by removing the buffer from global scope and adding into the toMAC-function? That's what I changed anyways Commented Jul 27, 2023 at 8:35
  • 1
    @HaraldLesan: If you make MAC_buffer local to toMAC(), you have to make it static, otherwise you would be getting back a pointer to unallocated stack space, which you cannot dereference (it's undefined behavior). But then, toMAC() is not pure. If you really want it pure, make it return the array encapsulated inside a struct. Commented Jul 27, 2023 at 8:45
  • 1
    @HaraldLesan As Edgar said, putting it inside the function will remove it from memory when the function exits, so you won't be able to use it outside. If you really want to avoid that global, the solution I would use is to allocate it outside and pass it to the function: uint8_t* toMAC(String s, uint8_t *MAC_buffer, uint8_t MAC_length). But generally speaking I avoid dynamic memory on uC, so usually buffers are usually global in my code.
    – frarugi87
    Commented Jul 27, 2023 at 8:55
  • 1
    I might be nitpicking here, but charToHex should probably be called fromHexChar or similar. We're not converting anything to hex, we're converting from hex.
    – tkausl
    Commented Jul 27, 2023 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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