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



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

我将从网络服务器输入字段接收字符串。我写了一些测试代码来确定存储和转换是否有效。事实证明并非如此。当我想存储 MAC 地址时,我不知道如何将字符数组转换为字节数组并忽略一些字符,例如":"。存储SSID,密码和通道效果很好,但MAC地址不行。

以下是写入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转换为字节/uint8_t数组,我可以将其存储在我的结构中,稍后将用于ESP的WiFi.begin功能...

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

如果我理解正确,您希望从网络服务器存储新的SSID和密码。去年我做了一个大项目,自己创建了一个WiFi管理器。我刚刚找到了我创建的图书馆,这是我如何将新的SSID和pwd上传到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 = "";
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

所以第一个字节是正确的。其余的都错了。