casting char or string to a uint8_t array

New to working with C based languages. I'm confused by the types that I keep getting told I can't convert or cast from one kind to another.

I have a sketch on my ESP8266 that takes user information from a web page (user enters an ID for a LIFX bulb). I save that data into EEPROM, and then after a restart, I pull it back out, as such:

 // Load Saved Configuration from EEPROM
boolean loadSavedConfig() {
  Serial.println("Reading Saved Config....");
  String ssid = "";
  String password = "";
  String eventnm = "";
  String lifxbulbid = "";

  if (EEPROM.read(0) != 0) {
    for (int i = 0; i < 32; ++i) {
      ssid += char(EEPROM.read(i));
    }
    Serial.print("SSID: ");
    Serial.println(ssid);
    for (int i = 32; i < 96; ++i) {
      password += char(EEPROM.read(i));
    }
    Serial.print("Password: ");
    Serial.println(password);
    for (int i = 96; i < 128; ++i) {
      lifxbulbid += char(EEPROM.read(i));  //local variable for immediate temporary use
      lifx_Id += char(EEPROM.read(i));  //global variable for use in sending UDP packet data
      }

    Serial.print("Lifx Bulb ID: ");
    Serial.println(lifxbulbid);    
    WiFi.begin(ssid.c_str(), password.c_str());
    return true;
  }
  else {
    Serial.println("Saved Configuration not found.");
    return false;
  }
}

Once I have this value, I am told I need it in a uint8_t array to pass onto the LIFX UDP LAN protocol.

ie:

 uint8_t dest[] = {0xd0, 0x73, 0xd5, 0x13, 0xe7, 0x10};

An example of the Id of the bulb is normally (printed on the bulb): D073D513E710 but I can enter them into the webpage however I want - so I can convert to the "hex" code manually or not.

I've been working with my variable " lifx_Id " as a String and as char - but haven't been able to convert or cast it for the protocol to use. How can I do that?

I'm assuming it's easier to parse it out of the webpage - but EEPROM memory isn't huge, so I felt that saving it as a 12 digit string was easiest and then casting it appropriately after would work. But so far no luck.

So to summarize - ideally - take a string or char value like - "ABCD12345678" and cast it to a uint8_t array as such: "uint8_t dest[] where it equals {0xd0, 0x73, 0xd5, 0x13, 0xe7, 0x10}"

Thanks for any insight and assistance!

So to summarize - ideally - take a string or char value like - "ABCD12345678" and cast it to a uint8_t array as such: "uint8_t dest[] where it equals {0xd0, 0x73, 0xd5, 0x13, 0xe7, 0x10}"

You can forget that. That is NOT how a cast works. A cast means here is data of one type that you should use as though it was another type. The key there is type, NOT format. You have data in one format that you need in another format.

If you have a string "D073D513E710" that you need as a byte array containing 0xd0, 0x73, 0xd5, 0x13, 0xe7, 0x10, you need to extract two characters at a time, into another array with a NULL terminator, and pass that array to strtoul() to get a value to store in the dest array.

D0 -> 0xD0
73 -> 0x73
etc.

Thank you very much for the quick reply. I'll do some more reading with that in mind now and see if I can get that to work.

OK, stretching here a bit. At one point I could do this all day in python, but not in C++ I guess. I've modified the code as follows, and added a small section to try to pull 2 characters at a time from the string: "lifxbulbid". I then try to send them to a char array using .toCharArray and the indexes. In one error I received I saw that .toCharArray allowed for a buffer index. as in .toCharArray(buffer, length, location) I haven't yet tried using strtoul(), as I don't have an array that works yet.

How can I restructure the section to properly build the array on the fly?

// Load Saved Configuration from EEPROM
boolean loadSavedConfig() {
  Serial.println("Reading Saved Config....");
  String ssid = "";
  String password = "";
  String eventnm = "";
  String lifxbulbid = "";
  char charBuf[6];
  if (EEPROM.read(0) != 0) {
    for (int i = 0; i < 32; ++i) {
      ssid += char(EEPROM.read(i));
    }
    Serial.print("SSID: ");
    Serial.println(ssid);
    for (int i = 32; i < 96; ++i) {
      password += char(EEPROM.read(i));
    }
    Serial.print("Password: ");
    Serial.println(password);
    for (int i = 96; i < 128; ++i) {
      lifxbulbid += char(EEPROM.read(i));
      lifx_Id = lifxbulbid;
    }  
    Serial.print("Lifx Bulb ID: ");
    Serial.println(lifxbulbid);
    WiFi.begin(ssid.c_str(), password.c_str());

    //Bit added here to capture the string into an array//

    for (int i = 0; i < 13; ++i)  {
    (lifxbulbid.substring(i,i+1)).toCharArray(charBuf, 2, i);
    Serial.println(charBuf[i]); 
    }

    return true;
  }
  else {
    Serial.println("Saved Configuration not found.");
    return false;
  }
}

returned results in Serial:

Lifx Bulb ID: D073D513E710
0

(other odd characters like a:) 
y with an umlot
 ?
 smiley face
 square
 blank
 @
 
blank
blank
blank, etc

You KNOW how many characters you are going to read from EEPROM for the various purposes. So, quit pissing away resources on the String class.

for (int i = 0; i < 13; ++i)  {
    (lifxbulbid.substring(i,i+1)).toCharArray(charBuf, 2, i);
    Serial.println(charBuf[i]);
    }

So, you have a 6 element array that you extract 2 elements to. Then, you print charBuf[0], [1], [2], ..., [13]. I really have to ask why.

The substring length is 2, so I can't see why you are trying to extract characters from position 0, 1, 2, 3, ... 13 from the 2 character substring.

Thanks for the assistance. I'm used to using strings in other languages, so forgive my ignorance.

In your previous reply, you indicated I should create an array to pass 2 character elements into, then use strtoul() to pass that array into another.

So this is the first array, and the Serial.println is my debugging into serial so I can see what's happening - that's all. That line will be removed afterwards.

Can you advise how to correct what I have to grab 2 characters at a time and place them in the array appropriately? I'm only grabbing one at a time now, I guess.

changing it thus - results in single character buffer

    //Bit added here to capture the string into an array//
    
    for (int i = 0; i < 13; ++i)  {
    (lifxbulbid.substring(i,i+1)).toCharArray(charBuf, 2);

Can you advise how to correct what I have to grab 2 characters at a time and place them in the array appropriately? I'm only grabbing one at a time now, I guess.

The second argument to toCharArray() has some meaning. What do you think it means?

Hint: It is NOT the number of characters to extract.

Well the reference says it's a len: the size of the buffer (unsigned int). For some reason I was assuming it meant the size of the element buffer, not the entire array.

By pissing away resources - are you indicating I should take another tact here? Should I read from EEPROM directly into an array somehow? I tried that earlier and was getting errors about converting char to char.

I've edited the code now so that I am getting two elements per run through the loop, but it's overwriting the array each time I think.

    for (int i = 0; i < 11; ++i)  {
      (lifxbulbid.substring(i,i+2)).toCharArray(charBuf,6);
      Serial.println(charBuf);  // here for debugging only
      ++i;
}

How to save it into a stable array and pass that into the needed uint8_t values?

Well the reference says it's a len: the size of the buffer (unsigned int). For some reason I was assuming it meant the size of the element buffer, not the entire array.

It IS the length of the buffer. But, a buffer of length 2 can only hold one character along with the terminating NULL.

By pissing away resources - are you indicating I should take another tact here? Should I read from EEPROM directly into an array somehow?

Yes.

I tried that earlier and was getting errors about converting char to char.

That, of course, is nonsense. You have have gotten errors about converting const char to char, or char * to char, but no conversion is needed to get from char to char, so there is no possible way to get that "error".

I've edited the code now so that I am getting two elements per run through the loop, but it's overwriting the array each time I think.

Of course the charBuf buffer is overwritten each time.

    byte hexVals[6];
    byte hexIndx = 0;
    for (int i = 0; i < 11; i+=2)
    {
      (lifxbulbid.substring(i,i+2)).toCharArray(charBuf,6);
      Serial.println(charBuf);  // here for debugging only

      // Convert the string to a value, knowing that
      // the string is in base 16 format. Store the value
      // in the next position in the array, and increment 
      // the index into that array
      hexVals[hexIndx++] = strtoul(charBuf, NULL, 16);
    }

Of course, it really does not make sense to use two bytes in EEPROM to hold the hex representation of the value, when the hex value can be stored in one byte.

Thank you again.

You are right, of course, I was getting errors as you described, not as I did. I hesitated to put too much into the discussion to not obfuscate things.

Thank you for the code - I really do appreciate it. For lack of a formal programming education, I've struggled along with search results and trying to piece together the melange of code that works on Arduino.

I also appreciate the method in which you're formatting your responses - you're forcing me to dig deeper, asking me questions, which drives learning - thank you.

I've made the proposed changes and it's working great! I can plug the ID into the website and it gets used as the MAC address in the UDP packets appropriately.

I may spend time to figure out why LIFX protocol isn't taking the MAC when sending the payload (It's only responding when using a blank destination and the IP directly), but I haven't gotten any response from their forum as of yet.

Really - again - thank you very much for taking the time to work with me on this. I've seen so many forums where people respond with such condescension that it's nearly demoralizing.

Regards

kwhizr:
I also appreciate the method in which you're formatting your responses - you're forcing me to dig deeper, asking me questions, which drives learning - thank you.

You're one of the few newbies here that likes that method :wink: I've seen a lot of people get frustrated with it.

kwhizr:
Thank you for the code - I really do appreciate it. For lack of a formal programming education, I've struggled along with search results and trying to piece together the melange of code that works on Arduino.

I think that it's the first time that I've seen PaulS post a code.

I think that it's the first time that I've seen PaulS post a code.

You haven't been paying attention.

Seems to be my strong point :wink: