Preferences.h and pubsubclient.h not working

I have a weird problem (or I might be an idiot).
I have a basic sketch that sets basic things about my system using preferences. It sets wifi ssid, wifi password, mqtt server, mqtt username mqtt password into preferences . In this way I can then push new images via ota and the new images can be on a public cloud and the source code can be public as well.
Now to the problem. I set the things above and when I push the following image to the device connecting to the wifi works like a charm but not connecting to the mqtt broker. If I then comment out everything regarding Prefrences and mqtt, and add servername, username and password in the code (the now comment out section) it works. As you see I print the server name and user to serial and it looks just fine. I am using hivemq is that effecting anything (probably...).
What can be wrong?

#include <WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <Preferences.h>
//---- WiFi settings
Preferences preferences;
const char* ssid = "";
const char* password = "";
//---- MQTT Broker settings
//If I hardcode the servername, username and password it works
const char* mqtt_server = "";
//const char* mqtt_server = "******************.eu.hivemq.cloud";
const char* mqtt_username = "";
//const char* mqtt_username = "******";
const char* mqtt_password = "";
//const char* mqtt_password = "********";

//Device attr
const char* device_type = "sprinkler";
const char* location = "garden";
const char* device_name = "sprinkler1";

const int mqtt_port = 8883;

WiFiClientSecure espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;

#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];


static const char* root_ca PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)EOF";

void setup() {
  Serial.begin(9600);
  preferences.begin("settings", false);
  String WIFI_SSID = preferences.getString("WIFI_SSID", "");
  String WIFI_SECRET = preferences.getString("WIFI_SECRET", "");
  String SETTING_MQTT_SERVER = preferences.getString("MQTT_SERVER", "");
  String SETTING_MQTT_USER = preferences.getString("MQTT_USER", "");
  String SETTING_MQTT_PASSWORD = preferences.getString("MQTT_PASSWORD", "");
  String TEST = preferences.getString("tesr", "");
  preferences.end();
  Serial.println();
  Serial.println("###############################################");
  Serial.println("Settings: " + SETTING_MQTT_SERVER + "," + SETTING_MQTT_USER);

  if (!WIFI_SSID.equals("")) {
    ssid = WIFI_SSID.c_str();
  }
  if (!WIFI_SECRET.equals("")) {
    password = WIFI_SECRET.c_str();
  }

// If the following 9 lines is commented out it works
   if (!SETTING_MQTT_SERVER.equals("")) {
      mqtt_server = SETTING_MQTT_SERVER.c_str();
   }
   if (!SETTING_MQTT_USER.equals("")) {
    mqtt_username = SETTING_MQTT_USER.c_str();
   }
   if (!SETTING_MQTT_PASSWORD.equals("")) {
     mqtt_password = SETTING_MQTT_PASSWORD.c_str();
   }
  Serial.println("Settings:mqtt_server:" + String(mqtt_server)+",mqtt_username:" + String(mqtt_username));
  Serial.print("\nConnecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  Serial.println("\nWiFi connected\nIP address: ");
  Serial.println(WiFi.localIP());

  while (!Serial) delay(1);

  espClient.setCACert(root_ca);
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) reconnect();

  client.loop();
  StaticJsonDocument<200> doc;
  doc["sensor"] = "gps";
  doc["time"] = 1351824120;
  doc["data"] = "gps";

  String topic = String("myhome/") + String(location) + String("/") + String(device_name);
  publishMessage(topic.c_str(), doc, true);
  delay(2000);
}

//=======================================================================Function=================================================================================

void reconnect() {
  // Loop until we’re reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection…");
    String clientId = "ESP8266Client-";  // Create a random client ID
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
      Serial.println("connected");
      //Subscribe to both location and device_type
      String location_str = String("myhome/" + String(location));
      client.subscribe(location_str.c_str());
      location_str += "/" + String(device_name);
      client.subscribe(location_str.c_str());
      String device = "device/" + String(device_type);
      client.subscribe(device.c_str());
      device += "/" + String(device_name);

      client.subscribe(device.c_str());
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");  // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//=======================================
// This void is called every time we have a message from the broker

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.println("callback");

  JsonDocument doc;
  DeserializationError error = deserializeJson(doc, payload);
  String output;
  serializeJson(doc, output);
  Serial.println("Message arrived [" + String(topic) + "]" + output);
}

//======================================= publising as string
void publishMessage(const char* topic, JsonDocument payload, boolean retained) {

  char buffer[256];
  size_t n = serializeJson(payload, buffer);
  client.publish(topic, buffer, retained);
}

Hi @OlleD ,

Welcome to the forum..
Sorry for the wait..

couple things wrong here..

first..

const char* ssid = "";

i don't claim to be a c expert, but constant too me means it will constantly be..

and then..
it works for wifi connection because you do this in setup..
if you waited and connected in your loop, you'd have notice it wasn't working either..

ssid = WIFI_SSID.c_str();

the above doesn't copy the contents but rather make ssid point to the other..
as these vars are declared locally inside of setup they lose focus in the loop..
they turn to goobly goop..

easiest way out of this is to changed declarations to fixed char buffer big enough to hold its value and don't forget space for ending "\n" null..

then use strcpy to copy the contents from your temp Strings into the char arrays..

here's my test sketch..

#include <Preferences.h>


//---- WiFi settings
Preferences preferences;
 char ssid[20] = "\n";
 char password[20] = "\n";
//---- MQTT Broker settings
//If I hardcode the servername, username and password it works
char mqtt_server[100] = "\n";
//const char* mqtt_server = "******************.eu.hivemq.cloud";
char mqtt_username[20] = "\n";
//const char* mqtt_username = "******";
char mqtt_password[20] = "\n";
//const char* mqtt_password = "********";



void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32!");
   preferences.begin("settings", false);
   preferences.putString("WIFI_SSID", "ssid");
   preferences.putString("WIFI_SECRET", "password");
   preferences.putString("MQTT_SERVER", "www.server.com/eu/site");
   preferences.putString("MQTT_USER", "user");
   preferences.putString("MQTT_PASSWORD", "pass");

  String WIFI_SSID = preferences.getString("WIFI_SSID", "");
  String WIFI_SECRET = preferences.getString("WIFI_SECRET", "");
  String SETTING_MQTT_SERVER = preferences.getString("MQTT_SERVER", "");
  String SETTING_MQTT_USER = preferences.getString("MQTT_USER", "");
  String SETTING_MQTT_PASSWORD = preferences.getString("MQTT_PASSWORD", "");
  String TEST = preferences.getString("tesr", "");
  preferences.end();
  Serial.println();
  Serial.println("###############################################");
  Serial.println("Settings: " + SETTING_MQTT_SERVER + "," + SETTING_MQTT_USER);

  if (!WIFI_SSID.equals("")) {
    strcpy(ssid, WIFI_SSID.c_str());
  }

  if (!WIFI_SECRET.equals("")) {
    strcpy(password, WIFI_SECRET.c_str());
  }

// If the following 9 lines is commented out it works
   if (!SETTING_MQTT_SERVER.equals("")) {
      strcpy(mqtt_server, SETTING_MQTT_SERVER.c_str());
   }
   if (!SETTING_MQTT_USER.equals("")) {
    strcpy(mqtt_username, SETTING_MQTT_USER.c_str());
   }
   if (!SETTING_MQTT_PASSWORD.equals("")) {
     strcpy(mqtt_password , SETTING_MQTT_PASSWORD.c_str());
   }
  Serial.println("Settings:mqtt_server:" + String(mqtt_server)+",mqtt_username:" + String(mqtt_username));

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10); // this speeds up the simulation
  Serial.println("Loop");
  Serial.println("Settings:mqtt_server:" + String(mqtt_server)+",mqtt_username:" + String(mqtt_username));
  delay(5000);

}

good luck.. ~q

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.