使用 ESP8266/8285 将字符串从 Web 服务器转换为字节数组

Convert String from web server to byte array with ESP8266/8285

我想在我的 ESP8285 的 flash/EEPROM 上存储 WiFi 凭证和一些其他配置。

我将从网络服务器输入字段接收字符串。我写了一些测试代码来确定存储和转换是否有效。事实证明它没有。当我想存储 MAC 地址时,我无法弄清楚如何将 char 数组转换为字节数组并忽略一些字符,如“:”。存储 SSID、密码和频道效果很好,但 MAC-address 不行。

这是我写入 EEPROM 时的代码片段:

void writeCredentials() {
  String newSSID = "WRT";
  String newPass = "45568798789098794879784";
  String newBSSID = "3A:79:16:A8:B5:76";
  char buff[sizeof(settings.eeBSSID)];
  byte mac[6];
  char chBuff[3];
  char *ptr;
  newBSSID.toCharArray(buff, newBSSID.length() + 1);
  Serial.println(buff);
  ptr = strtok(buff, ":");
  int index = 0;
  while (ptr != NULL) {
    strcpy(chBuff, ptr);
    Serial.print(" Mac: ");
    Serial.print(chBuff);
    sscanf(&chBuff[2], "%02xd", &mac[index]); //no idea here maybe completely wrong
    index++;
    ptr = strtok(NULL, ":");
  }
  Serial.println("");
  newSSID.toCharArray(settings.eeSSID, newSSID.length() + 1);
  newPass.toCharArray(settings.eePass, newPass.length() + 1);
  for (int i = 0; i < sizeof(mac); i++) {
    Serial.println(char(mac[i]));
  }
  settings.eeChannel = 12345;
  memcpy(settings.eeBSSID, mac, sizeof(mac));
  EEPROM.put(0, settings);
  Serial.println("Settings saved!");
}

出于测试目的,我将字符串放入 writeCredentials() 函数中。稍后它们将来自网络服务器文本输入表单。一切都在这样的配置结构中进行管理:

typedef struct WiFi_Settings {
  char eeSSID[32];
  char eePass[32];
  byte eeBSSID[6];
  int eeChannel;
};

WiFi_Settings settings {
  "",
  "",
  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  1
};

我花了好几个小时才将 newBSSID 转换为 byte/uint8_t 数组,我可以将其存储在我的结构中,稍后将用于 ESP 的 WiFi.begin 函数...

使用 strtok、sscanf 测试了很多变化,并尝试将 char 数组(存储在 buff 中)拆分为 2 个 char 片段的位,然后我可以将其转换为一个字节并将其传递给字节数组,但每次都有一些东西不起作用。也许有人可以帮助我?

如果我理解正确的话,你想从网络服务器存储新的 SSID 和密码。我去年做了一个大项目并创建了一个 WiFi 管理器 myself.I 刚刚找到了我创建的库,下面是我如何将新的 SSID 和密码上传到 EEPROM。希望对您的问题有所帮助。

.
.
.
//New_ssid and New_pass were declared has String
if(New_Input == true){
        int  i=0;
        char *SNew_ssid = &New_ssid[0u];  //Convert String to char 
        char *SNew_pass = &New_pass[0u];
        Serial.print("Trying to connect to: ");
        Serial.println(New_ssid);
        WiFi.mode(WIFI_AP_STA);    //AP e station
        WiFi.begin(SNew_ssid,SNew_pass);   //Connecting to new WiFi
        while(WiFi.status() != WL_CONNECTED && i<100){
            delay(200);
            Serial.print(".");
            i++;
        }
        if(WiFi.status() == WL_CONNECTED){  //Connected to new WiFi
            Serial.println("");
            //cleaning EEPROM
            if(New_ssid.length() > 0 && New_pass.length() > 0){
                Serial.println("Cleaning EEPROM...");
                for(i = 0;i < 96;i++){
                    EEPROM.write(i,0);
                }
            }
            //Writing to EEPROM
            Serial.println("Writing SSID to EEPROM...");
            for(i = 0;i < New_ssid.length(); i++){
                EEPROM.write(i,New_ssid[i]);

            }
            Serial.println("Writing Password to EEPROM...");
            for(i = 0;i < New_pass.length(); i++){
                EEPROM.write(32+i,New_pass[i]);
            }
            EEPROM.commit();
.
.
.

下面是从EEPROM中获取数据的方法不知道对你有没有帮助。这部分代码不是WiFiManager库而是主要代码。

.
.
.
Str_Buffer = "Reading SSID and PASSWORD from EEPROM...";
    SendToPrinter(0,"aa",0);
    eSSID = "[=11=]";
    for(int i = 0; i < 32; i++){
        eSSID += char(EEPROM.read(i));
        //Str_Buffer = char(EEPROM.read(i));
    }
    for(int i = 32; i < 96; i++){
        ePASS += char(EEPROM.read(i));
    }


    //Ligação à rede Wifi
    WiFi.mode(WIFI_STA); //Modo station
    if(eSSID.length() > 1){  //If got any SSID stored at EEPROM
            WiFi.begin(eSSID.c_str(),ePASS.c_str());
            Str_Buffer = "Connecting to: ";
            Str_Buffer += eSSID.c_str();
            SendToPrinter(0,"aa",0);
        }else{
        WiFi.begin(ssid,pass);
        Str_Buffer = "Connecting to: "; //Rede xhockware como definição
        Str_Buffer += ssid;
        SendToPrinter(0,"aa",0);
    }
    int i = 0;

    //Checking Wi-Fi status
    while(WiFi.status() != WL_CONNECTED && i<50){
        delay(200);
        Serial.print(".");
        i++;
    }
    if(WiFi.status() == WL_CONNECTED){
        Serial.println("");
        Str_Buffer = "Connected to network";
        SendToPrinter(0,"aa",0);
        flag_ifWifiConnected = true;
    }
    if(i == 50){
        Serial.println("");
        Str_Buffer = "Error connecting to network";
        SendToPrinter(0,"aa",0);
        flag_ifWifiConnected = false;
    }
.
.
.

我简化了代码以解决 mac 地址问题。

typedef struct WiFi_Settings {
  byte eeBSSID[6];
};

WiFi_Settings settings {
  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
};

void writeCredentials() {
  String newBSSID = "3A:79:16:A8:B5:76";
  char buff[18];
  newBSSID.toCharArray(buff, newBSSID.length() + 1);
  sscanf(buff, "%02xhhd:%02xhhd:%02xhhd:%02xhhd:%02xhhd:%02xhhd", &settings.eeBSSID[0], &settings.eeBSSID[1], &settings.eeBSSID[2], &settings.eeBSSID[3], &settings.eeBSSID[4], &settings.eeBSSID[5]);
  EEPROM.put(0, settings);
  Serial.println("Settings saved!");
  Serial.print("Saved MAC: ");
  for (int i = 0; i < sizeof(settings.eeBSSID); i++) {
    Serial.print(settings.eeBSSID[i]);
    if (i < 5)  Serial.print(":");
  }
  Serial.println("");
}

我尝试了 P. Kouvarakis 提到的解决方案。遗憾的是它不能完全工作。串行输出:

Settings saved!
Saved MAC: 58:0:0:0:0:0

所以第一个字节是对的。其他都错了。