3

I have a project that uses an MQTT service, and I'm wondering how to best store the configuration settings (server, user, password, port) for the service as right now they are just hard-coded into some constants.

I saw that EEPROM can be used for this but I'm not sure it is the best way. I went to look at the code for WifiManager to see how it accomplishes this task for the SSID and password since it works so well and it removed its EEPROM dependency back in 2015: https://github.com/tzapu/WiFiManager/commit/659df9cb277c5f93946d9d8795e39a5ae5863ab1

I can't figure out how those settings are persisted.

If EEPROM is the best way for storing something like this, I'd like to write my values without overwriting/corrupting existing values, is that possible? How can I set the initial values of the EEPROM to the constants that I need?

Edit: well after digging into the esp8266/Arduino repository I found that the WiFi.SSID() and WiFi.psk() settings come from wifi_station_get_config and stored with wifi_station_set_config although I haven't found how those work so I think EEPROM might be the way to go here, I just need a bit of guidance and clarification on the right way to use it.

  • 2
    as an alternative, have you considered looking into using SPIFFS (but EEPROM is fine - the parts that were removed in WifiManager had to do with storing the SSID/password - the ESP8266 already does this "natively" (don't ask, I don't know the details of where) – Jaromanda X Nov 8 '17 at 5:31
  • 1
  • @JaromandaX I haven't used SPIFFS before, I'll look into that. – travis Nov 8 '17 at 5:42
  • 1
    +infinity for SPIFFS over EEPROM. use SPIFFS, it's easy and great. – dandavis Nov 8 '17 at 21:41
4

Thanks to Jaromanda X and Juraj for the SPIFFS recommendation. I was able to use this block of SPIFFS code as an example and safely store settings in my project outside of the compiled source.

To upload files to my ESP8266, I followed the installation and usage instructions for the ESP8266 filesystem plugin for the standard Arduino IDE.

First, I created a .gitignore file and added this so that none of the actual values would get added to the repository:

# MQTT config info
data/config.json

Then I created a data folder and added a config.json file that had all the configuration properties that I need to reference:

{
  "cloudmqtt_server": "***.cloudmqtt.com",
  "cloudmqtt_user": "********",
  "cloudmqtt_pass": "************",
  "cloudmqtt_port": 10000 
}

Following the example above, I added #include <FS.h> at line #1 (as well as #include <ArduinoJson.h> for parsing the JSON) and have this block to instantiate the variables with dummy values that will be replaced by the actual values from the JSON file:

// MQTT pub/sub for the servo functions
#define CLOUDMQTT_CONFIG  "/config.json"
// these values are loaded from a config.json file in the data directory
char cloudmqtt_server[18] = "***.cloudmqtt.com";
int  cloudmqtt_port       = 0;
char cloudmqtt_user[9]    = "********";
char cloudmqtt_pass[13]   = "************";

Then in the setup I have this block to load the values from the config:

if (SPIFFS.begin()) {
  Serial.println("mounted file system");

  // parse json config file
  File jsonFile = GetFile(CLOUDMQTT_CONFIG);
  if (jsonFile) {
    // Allocate a buffer to store contents of the file.
    size_t size = jsonFile.size();
    std::unique_ptr<char[]> jsonBuf(new char[size]);
    jsonFile.readBytes(jsonBuf.get(), size);

    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject(jsonBuf.get());
    if (json.success()) {
      strcpy(cloudmqtt_server, json["cloudmqtt_server"]);
      cloudmqtt_port = json["cloudmqtt_port"];
      strcpy(cloudmqtt_user, json["cloudmqtt_user"]);
      strcpy(cloudmqtt_pass, json["cloudmqtt_pass"]);
    } else {
      Serial.println("failed to load json config");
    }
    jsonFile.close();
  }
}

I'm not sure if there's a better way, but this way works for me: https://github.com/dieseltravis/esp8266-projects/tree/master/servo-demo

  • If you use WiFiManager you could also ask for the MQTT parameters directly from the captive portal, then save to SPIFFS. – FarO Aug 12 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.