Davide Davide - 2 months ago 110
C Question

Convert IP or MAC address from string to byte array (Arduino or C)

I would convert myString "100.200.300.400" to byte array [4].
I'm a "bit" confused, this is right or need i to use a foreach for reading a single number?

String myString = "100.200.300.400";
byte myByteArray[4];
myString.getBytes(myByteArray,4);


Finally I want to print to the array to serial. This should be right.

for (i=0; i<4; i++) {
Serial.print(myByteArray[i]);
Serial.print("."); //delimiter
}


Were I am going wrong? I got 49,48,48,0 !

Answer

If you are trying to get from a string like "100.150.200.250" to a byte array like { 100, 150, 200, 250 }, you need to extract the string representation for each number and convert (parse) them into a binary representation before storing them in the byte array.

The way you are trying to do this, you are just converting the first four bytes from the string, i.e. "100.", to the binary representation of each character, which turns out to be { 49, 48, 48, 0 }. You can look that up in an ASCII table.

Also remember that, as you are storing this on a byte array, it will only support values from 0 to 255.

As you are programming on small microcontroller, I would advise against using the String class. You might run into trouble when your programs get bigger and you start using lots of strings. Try to learn how to use character arrays instead and you will avoid running into memory issues. Remember the Arduino has just 2KB of RAM!

Here is a function you can use to make that conversion using the strtoul() function:

void parseBytes(const char* str, char sep, byte* bytes, int maxBytes, int base) {
    for (int i = 0; i < maxBytes; i++) {
        bytes[i] = strtoul(str, NULL, base);  // Convert byte
        str = strchr(str, sep);               // Find next separator
        if (str == NULL || *str == '\0') {
            break;                            // No more separators, exit
        }
        str++;                                // Point to next character after separator
    }
}

You can then call it like this to convert an IP address (base 10):

const char* ipStr = "50.100.150.200";
byte ip[4];
parseBytes(ipStr, '.', ip, 4, 10);

Or like this to convert a MAC address (base 16):

const char* macStr = "90-A2-AF-DA-14-11";
byte mac[6];
parseBytes(macStr, '-', mac, 6, 16);
Comments