使用 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
所以第一个字节是对的。其他都错了。
我想在我的 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
所以第一个字节是对的。其他都错了。