[GH-ISSUE #1562] HELP NEEDED to save and use a custom parameter #1333

Open
opened 2026-02-28 01:29:38 +03:00 by kerem · 11 comments
Owner

Originally created by @championc on GitHub (Feb 14, 2023).
Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1562

Can someone point me towards an code example where I can save an IP Address added as a custom parameter, to then be used in the script. I want to connect to an MQTT server. So I have a custom parameter to allow the user to enter the IP address of the server.

I have a basic WifiManager working, permitting the entry of my SSID and creds and it saves the data. I believe that the MQTT Server IP Address is being saved from the custom parameter, but I am struggling to understand as to how to retrieve this when my esp8266 restarts, for me to read this and pass it into a variable in my script.

Thanks in advance

Originally created by @championc on GitHub (Feb 14, 2023). Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1562 Can someone point me towards an code example where I can save an IP Address added as a custom parameter, to then be used in the script. I want to connect to an MQTT server. So I have a custom parameter to allow the user to enter the IP address of the server. I have a basic WifiManager working, permitting the entry of my SSID and creds and it saves the data. I believe that the MQTT Server IP Address is being saved from the custom parameter, but I am struggling to understand as to how to retrieve this when my esp8266 restarts, for me to read this and pass it into a variable in my script. Thanks in advance
Author
Owner

@delugeia commented on GitHub (Feb 15, 2023):

I cannot speak to ESP8266, but on ESP32, here are the steps I take to ask for an optional field...

presuming you have a WiFiManager object called "wm"...
WiFiManager wm;

Create the parameter...
WiFiManagerParameter myField("myFieldLabel", "Enter Your Field Value");

Add the parameter to your object...
wm.addParameter(&myParameter);

Then after WiFiManager is triggered, the SSID/PASS form will have your field.
You can read what was entered using the getValue() method, which returns a char* array pointer...
myParameter.getValue();

How you store that value, e.g. SPIFFS, is up to you.

Hope this helps.

-- Not An Expert

<!-- gh-comment-id:1430557672 --> @delugeia commented on GitHub (Feb 15, 2023): I cannot speak to ESP8266, but on ESP32, here are the steps I take to ask for an optional field... presuming you have a WiFiManager object called "wm"... `WiFiManager wm;` Create the parameter... `WiFiManagerParameter myField("myFieldLabel", "Enter Your Field Value");` Add the parameter to your object... `wm.addParameter(&myParameter);` Then after WiFiManager is triggered, the SSID/PASS form will have your field. You can read what was entered using the getValue() method, which returns a char* array pointer... `myParameter.getValue();` How you store that value, e.g. SPIFFS, is up to you. Hope this helps. -- Not An Expert
Author
Owner

@championc commented on GitHub (Feb 15, 2023):

Thanks for that

In my case, I had initially used the following

[code]
WiFiManagerParameter custom_mqtt_server("my_mqttServer","MQTT Server IP Address","",15);
wifiManager.addParameter(&custom_mqtt_server);
.
.
strcpy(mqtt_server, custom_mqtt_server.getValue());
.
.
Serial.print("Attempting MQTT connection...");
updateOLED("Connect To", mqtt_server, "", "MQTT.");
[/code]

But this didn't work. So in my code, before my Serial.print, should I be using

const char* mqtt_server = custom_mqtt_server.getValue();

And if I stored several values with the wm.addParameter(&myParameter); would myParameter.getValue(); then return the string of values stored ?

<!-- gh-comment-id:1431922871 --> @championc commented on GitHub (Feb 15, 2023): Thanks for that In my case, I had initially used the following [code] WiFiManagerParameter custom_mqtt_server("my_mqttServer","MQTT Server IP Address","",15); wifiManager.addParameter(&custom_mqtt_server); . . strcpy(mqtt_server, custom_mqtt_server.getValue()); . . Serial.print("Attempting MQTT connection..."); updateOLED("Connect To", mqtt_server, "", "MQTT."); [/code] But this didn't work. So in my code, before my Serial.print, should I be using const char* mqtt_server = custom_mqtt_server.getValue(); And if I stored several values with the wm.addParameter(&myParameter); would myParameter.getValue(); then return the string of values stored ?
Author
Owner

@delugeia commented on GitHub (Feb 16, 2023):

The "myParameter" was meant to be an example. And a poor one at that since I changed to "myField" later on in my example.

I should point out that I've only been doing arduino stuff for a couple of years, am in no way an expert, and I have very little experience with WiFiManager. But I got it to work and I do use it.

You can create however many parameters you like, and use whatever variables you want to call them. But whatever parameters you create, you must STORE THEM YOURSELF after the Web Portal connects to your WiFi. They will NOT persist, so the next time the device resets, reboots, etc. they will be gone. Even connecting to the device with WiFi manager resets the device. And this has nothing to do with the resetSettings() method.

I created an overly commented simple example below. I can only say this works for me, my setup, my wifi, and my device (ESP32).

Good Luck!

main.txt

#include <Arduino.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager

WiFiManager wm;

void setup() {
Serial.begin(115200);
Serial.println(">> SETUP BEGIN");

// call setDebugOutput if you want to see WM's messages
wm.setDebugOutput(true, "\t\t *wm: ");

// call resetSettings() only to clear the SSID and password
// let it run for a few seconds and then comment out this line and reflash
// if you leave it in, you'll have to go through its Web Portal every time
// wm.resetSettings();

// how long WiFiManager should wait trying the stored password (if there is one)
wm.setConnectTimeout(10);

// add your parameters here, can be named anything, "myFoo" and "myBar" are examples
WiFiManagerParameter myFoo("myFoo", "Enter your Foo (Max 18 characters)", "boring default foo", 18);
WiFiManagerParameter myBar("myBar", "What Bar do you frequent? (max 32)", "some random pub", 32);
wm.addParameter(&myFoo);
wm.addParameter(&myBar);

bool wmConnectResult = wm.autoConnect("WinterNetIsComing"); // Anonymous AP Name

// you can check to see if it was able to connect to the WiFi SSID with given password
// in this case, if it fails, I'm just clearing the settings and rebooting
if (!wmConnectResult) {
Serial.println(">> OOPS... Connection Failed.");
Serial.println(">> Rebooting in 5 Seconds.");
delay(5000);
wm.resetSettings();
ESP.restart();
} else {
Serial.println(">> YAY! We Connected!");
}

// you can use getValue() to get the results of what was entered
// NOTE: unlike the SSID and PASSWORD, these are NOT stored in NVM.
// You have to save them yourself using SPIFFS, LittleFS, or some other persistent means.
// Otherwise they will be GONE the next time the device reboots or resets!

Serial.printf(">> Your Foo: %s\n", myFoo.getValue());
Serial.printf(">> Your Bar: %s\n", myBar.getValue());

Serial.println(">> SETUP END");
}

void loop() {
// normal Arduino loop() where you can do whatever loopy stuff you do
static bool firstLoop = true;

if (firstLoop) {
Serial.println(">> LOOP BEGIN");
firstLoop = false;
}
}

<!-- gh-comment-id:1432567017 --> @delugeia commented on GitHub (Feb 16, 2023): The "myParameter" was meant to be an example. And a poor one at that since I changed to "myField" later on in my example. I should point out that I've only been doing arduino stuff for a couple of years, am in no way an expert, and I have very little experience with WiFiManager. But I got it to work and I do use it. You can create however many parameters you like, and use whatever variables you want to call them. But whatever parameters you create, you must STORE THEM YOURSELF after the Web Portal connects to your WiFi. They will NOT persist, so the next time the device resets, reboots, etc. they will be gone. Even connecting to the device with WiFi manager resets the device. And this has nothing to do with the resetSettings() method. I created an overly commented simple example below. I can only say this works for me, my setup, my wifi, and my device (ESP32). Good Luck! [main.txt](https://github.com/tzapu/WiFiManager/files/10752633/main.txt) #include <Arduino.h> #include <WiFiManager.h> // https://github.com/tzapu/WiFiManager WiFiManager wm; void setup() { Serial.begin(115200); Serial.println(">> SETUP BEGIN"); // call setDebugOutput if you want to see WM's messages wm.setDebugOutput(true, "\t\t *wm: "); // call resetSettings() only to clear the SSID and password // let it run for a few seconds and then comment out this line and reflash // if you leave it in, you'll have to go through its Web Portal every time // wm.resetSettings(); // how long WiFiManager should wait trying the stored password (if there is one) wm.setConnectTimeout(10); // add your parameters here, can be named anything, "myFoo" and "myBar" are examples WiFiManagerParameter myFoo("myFoo", "Enter your Foo (Max 18 characters)", "boring default foo", 18); WiFiManagerParameter myBar("myBar", "What Bar do you frequent? (max 32)", "some random pub", 32); wm.addParameter(&myFoo); wm.addParameter(&myBar); bool wmConnectResult = wm.autoConnect("WinterNetIsComing"); // Anonymous AP Name // you can check to see if it was able to connect to the WiFi SSID with given password // in this case, if it fails, I'm just clearing the settings and rebooting if (!wmConnectResult) { Serial.println(">> OOPS... Connection Failed."); Serial.println(">> Rebooting in 5 Seconds."); delay(5000); wm.resetSettings(); ESP.restart(); } else { Serial.println(">> YAY! We Connected!"); } // you can use getValue() to get the results of what was entered // NOTE: unlike the SSID and PASSWORD, these are NOT stored in NVM. // You have to save them yourself using SPIFFS, LittleFS, or some other persistent means. // Otherwise they will be GONE the next time the device reboots or resets! Serial.printf(">> Your Foo: %s\n", myFoo.getValue()); Serial.printf(">> Your Bar: %s\n", myBar.getValue()); Serial.println(">> SETUP END"); } void loop() { // normal Arduino loop() where you can do whatever loopy stuff you do static bool firstLoop = true; if (firstLoop) { Serial.println(">> LOOP BEGIN"); firstLoop = false; } }
Author
Owner

@championc commented on GitHub (Feb 16, 2023):

Ok, that that was the reference to SPIFFS - I get it now

Thanks for the comprehensive replies. It was greatly appreciated

<!-- gh-comment-id:1432742084 --> @championc commented on GitHub (Feb 16, 2023): Ok, that that was the reference to SPIFFS - I get it now Thanks for the comprehensive replies. It was greatly appreciated
Author
Owner

@championc commented on GitHub (Feb 16, 2023):

Quick question - and hopefully a quick answer

I have the following, but the compiler does not like "mqtt_server = file.read();". How should this statement be formatted please ?

[code]
File file = SPIFFS.open("/mqtt_server.txt", "r");
mqtt_server = file.read();
Serial.print("Attempting MQTT connection...");
updateOLED("Connect To", mqtt_server, "", "MQTT.");
[/code]

<!-- gh-comment-id:1433867971 --> @championc commented on GitHub (Feb 16, 2023): Quick question - and hopefully a quick answer I have the following, but the compiler does not like "mqtt_server = file.read();". How should this statement be formatted please ? [code] File file = SPIFFS.open("/mqtt_server.txt", "r"); mqtt_server = file.read(); Serial.print("Attempting MQTT connection..."); updateOLED("Connect To", mqtt_server, "", "MQTT."); [/code]
Author
Owner

@delugeia commented on GitHub (Feb 17, 2023):

So NORMALLY I would have responded that this is beyond the scope of my random encounter support. And NORMALLY I would recommend doing a google search like "SPIFFS example code for ESP32". And NORMALLY I would have said that this is an GitHub Issues forum for WiFiManager, which as I understand it, is primarily intended to get you connected and save your WiFi credentials.

HOWEVER, I've been playing around with ChatGPT and its code writing ability. It is crazy impressive. So I decided to see what it would come up with and asked it to "Give me an example of how to write a string to a file and read it back using SPIFFS on an ESP32 using the Arduino framework."

It's example looks good to me. The only thing it forgot was to check if the filesystem had been formatted. You can either call SPIFFS.format(), or what I do is SPIFFS.begin(true) which tells it to format the SPIFFS partition only if it is needed.

Otherwise, everything below is ChatGPT's response...

Sure, here's an example of how to write a string to a file and read it back using SPIFFS on an ESP32 using the Arduino framework:

#include <FS.h>

void setup() {
  // Initialize SPIFFS
  if(!SPIFFS.begin()){
    Serial.println("Failed to mount file system");
    return;
  }

  // Open file for writing
  File file = SPIFFS.open("/myfile.txt", FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file for writing");
    return;
  }

  // Write string to file
  String data = "Hello, world!";
  file.println(data);
  file.close();

  // Open file for reading
  file = SPIFFS.open("/myfile.txt", FILE_READ);
  if(!file){
    Serial.println("Failed to open file for reading");
    return;
  }

  // Read string from file
  String contents = file.readStringUntil('\n');
  file.close();

  Serial.print("Contents of file: ");
  Serial.println(contents);
}

void loop() {
  // do nothing
}

In this example, the program initializes the SPIFFS file system using SPIFFS.begin() and then opens a file named "myfile.txt" for writing using SPIFFS.open(). It then writes the string "Hello, world!" to the file using file.println(), and closes the file using file.close().

The program then re-opens the same file for reading using SPIFFS.open() and reads the string from the file using file.readStringUntil(). Finally, it closes the file again using file.close() and prints the contents of the file to the serial monitor.

Note that this is a very simple example, and in a real-world application, you would need to handle errors and edge cases more carefully. Also note that SPIFFS has some limitations, such as a maximum file size of 1.9 MB and a limited number of write cycles before wearing out, so you may want to consider using other storage options for larger or more critical data.

<!-- gh-comment-id:1434099113 --> @delugeia commented on GitHub (Feb 17, 2023): So NORMALLY I would have responded that this is beyond the scope of my random encounter support. And NORMALLY I would recommend doing a google search like "SPIFFS example code for ESP32". And NORMALLY I would have said that this is an GitHub Issues forum for WiFiManager, which as I understand it, is primarily intended to get you connected and save your WiFi credentials. HOWEVER, I've been playing around with ChatGPT and its code writing ability. It is crazy impressive. So I decided to see what it would come up with and asked it to "Give me an example of how to write a string to a file and read it back using SPIFFS on an ESP32 using the Arduino framework." It's example looks good to me. The only thing it forgot was to check if the filesystem had been formatted. You can either call SPIFFS.format(), or what I do is SPIFFS.begin(true) which tells it to format the SPIFFS partition only if it is needed. Otherwise, everything below is ChatGPT's response... >> Sure, here's an example of how to write a string to a file and read it back using SPIFFS on an ESP32 using the Arduino framework: ```C++ #include <FS.h> void setup() { // Initialize SPIFFS if(!SPIFFS.begin()){ Serial.println("Failed to mount file system"); return; } // Open file for writing File file = SPIFFS.open("/myfile.txt", FILE_WRITE); if(!file){ Serial.println("Failed to open file for writing"); return; } // Write string to file String data = "Hello, world!"; file.println(data); file.close(); // Open file for reading file = SPIFFS.open("/myfile.txt", FILE_READ); if(!file){ Serial.println("Failed to open file for reading"); return; } // Read string from file String contents = file.readStringUntil('\n'); file.close(); Serial.print("Contents of file: "); Serial.println(contents); } void loop() { // do nothing } ``` In this example, the program initializes the SPIFFS file system using SPIFFS.begin() and then opens a file named "myfile.txt" for writing using SPIFFS.open(). It then writes the string "Hello, world!" to the file using file.println(), and closes the file using file.close(). The program then re-opens the same file for reading using SPIFFS.open() and reads the string from the file using file.readStringUntil(). Finally, it closes the file again using file.close() and prints the contents of the file to the serial monitor. Note that this is a very simple example, and in a real-world application, you would need to handle errors and edge cases more carefully. Also note that SPIFFS has some limitations, such as a maximum file size of 1.9 MB and a limited number of write cycles before wearing out, so you may want to consider using other storage options for larger or more critical data.
Author
Owner

@tablatronix commented on GitHub (Feb 19, 2023):

There are literally examples included for this

<!-- gh-comment-id:1436066146 --> @tablatronix commented on GitHub (Feb 19, 2023): There are literally examples included for this
Author
Owner

@delugeia commented on GitHub (Feb 19, 2023):

There are literally examples included for this

Agreed, however sometimes examples (in general) are difficult for beginners with little programming experience. Sometimes the examples are perfect but you don't know the terms to know which example relates to what you're trying to do. Sometimes the examples just suck. Sometimes the examples are good for those who are already close to the code, but not for those who aren't. Sometimes it helps those who are still learning to try and teach someone else what they know as it reinforces their own knowledge and familiarity with the topic.

Sometimes it just enjoyable to answer questions.

<!-- gh-comment-id:1436068200 --> @delugeia commented on GitHub (Feb 19, 2023): > There are literally examples included for this Agreed, however sometimes examples (in general) are difficult for beginners with little programming experience. Sometimes the examples are perfect but you don't know the terms to know which example relates to what you're trying to do. Sometimes the examples just suck. Sometimes the examples are good for those who are already close to the code, but not for those who aren't. Sometimes it helps those who are still learning to try and teach someone else what they know as it reinforces their own knowledge and familiarity with the topic. Sometimes it just enjoyable to answer questions.
Author
Owner

@tablatronix commented on GitHub (Feb 19, 2023):

Also SPIFFS is deprecated

<!-- gh-comment-id:1436069846 --> @tablatronix commented on GitHub (Feb 19, 2023): Also SPIFFS is deprecated
Author
Owner

@delugeia commented on GitHub (Feb 19, 2023):

Also SPIFFS is deprecated

You are correct. LittleFS would be better.

<!-- gh-comment-id:1436070269 --> @delugeia commented on GitHub (Feb 19, 2023): > Also SPIFFS is deprecated You are correct. LittleFS would be better.
Author
Owner

@mats-nk commented on GitHub (Mar 3, 2023):

I did the same as delugeia but with "LittleFS" in the question:

Give me an example of how to write or append a string to a file and read it back using LittleFS on an ESP32 or ESP8266 using the Arduino framework

#include "FS.h"
#include "LittleFS.h"

void setup() {
  Serial.begin(9600);
  if (!LittleFS.begin()) {
    Serial.println("LittleFS Mount Failed");
    return;
  }

  String myString = "Hello, World!";

  // Write the string to a file
  File file = LittleFS.open("/myFile.txt", "w");
  if (!file) {
    Serial.println("File creation failed");
    return;
  }
  file.print(myString);
  file.close();

  // Append the string to the file
  file = LittleFS.open("/myFile.txt", "a");
  if (!file) {
    Serial.println("File append failed");
    return;
  }
  myString = " This is an appended string.";
  file.print(myString);
  file.close();

  // Read the string from the file
  file = LittleFS.open("/myFile.txt", "r");
  if (!file) {
    Serial.println("File open failed");
    return;
  }
  String fileContent = file.readString();
  file.close();

  Serial.println(fileContent);
}

void loop() {
  // Empty loop
}

In this example, we first begin the LittleFS file system and create a string to write to a file. We then open a file called myFile.txt for writing and write the string to it using the print() method of the File class. We then close the file.

Next, we append another string to the file by opening it in append mode ("a") and writing the string to it using the print() method of the File class. We then close the file.

Finally, we reopen the file for reading using the open() method with the mode set to "r". We then read the contents of the file into a string using the readString() method and close the file.

Note that we check the return values of the LittleFS.begin(), LittleFS.open(), and File constructor methods to make sure they succeed before proceeding.

<!-- gh-comment-id:1454048670 --> @mats-nk commented on GitHub (Mar 3, 2023): I did the same as delugeia but with "LittleFS" in the question: Give me an example of how to write or append a string to a file and read it back using LittleFS on an ESP32 or ESP8266 using the Arduino framework ``` #include "FS.h" #include "LittleFS.h" void setup() { Serial.begin(9600); if (!LittleFS.begin()) { Serial.println("LittleFS Mount Failed"); return; } String myString = "Hello, World!"; // Write the string to a file File file = LittleFS.open("/myFile.txt", "w"); if (!file) { Serial.println("File creation failed"); return; } file.print(myString); file.close(); // Append the string to the file file = LittleFS.open("/myFile.txt", "a"); if (!file) { Serial.println("File append failed"); return; } myString = " This is an appended string."; file.print(myString); file.close(); // Read the string from the file file = LittleFS.open("/myFile.txt", "r"); if (!file) { Serial.println("File open failed"); return; } String fileContent = file.readString(); file.close(); Serial.println(fileContent); } void loop() { // Empty loop } ``` In this example, we first begin the LittleFS file system and create a string to write to a file. We then open a file called `myFile.txt` for writing and write the string to it using the `print()` method of the File class. We then close the file. Next, we append another string to the file by opening it in append mode (`"a"`) and writing the string to it using the `print()` method of the File class. We then close the file. Finally, we reopen the file for reading using the `open()` method with the mode set to `"r"`. We then read the contents of the file into a string using the `readString()` method and close the file. Note that we check the return values of the `LittleFS.begin()`, `LittleFS.open()`, and `File `constructor methods to make sure they succeed before proceeding.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/WiFiManager#1333
No description provided.