[GH-ISSUE #1395] Store the value of mqtt server address(pubsubclient) from custom parameter and reuse it dynamically #1195

Closed
opened 2026-02-28 01:28:57 +03:00 by kerem · 5 comments
Owner

Originally created by @shariq-azim on GitHub (Apr 15, 2022).
Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1395

Hardware

WiFimanager Branch/Release: Master
Esp32

Hardware: ESP-12e, esp01, esp25

Core Version: 2.4.0, staging

Description

I am trying to set the default value in the custom parameter first, but if there is a change of value i am trying to copy and update another variable that can be re-used as the mqtt server address. So that if the connection is lost it will try to connect again with the last known value. The following code runs one and connects properly during setup but if the connection is lost with MQTT server it wont connect as it would now have garbage value in it.

The obvious reason is because the previous value of the pointer is lost after the setup function exists.

I have tried so many variations but it is not working ,and unfortunately, the solutions in internet is mostly theory and not the code. Thus, i am reaching for the experts to help. Unfortunately, the solutions in internet is mostly theory and not the code.

Please help retrieve the value from a different function.

Version :2.03-alpha, 2.0.11 beta

Additional libraries:
Pubsubclient

Sketch

#BEGIN


#include <WiFi.h>
#include <WiFiClient.h>
//#include <WebServer.h> 
#include <ESPmDNS.h> 
#include <Update.h> 

#include <PubSubClient.h>//0.4
//#include <HTTPClient.h> //0.4
#include <ArduinoJson.h> //0.4  // https://github.com/bblanchon/ArduinoJson
#include<string.h> //0.4
#include<cstring> //0.4
#include <WiFiManager.h>
#include <Preferences.h>


bool InternetStatus = false; 

// Your WiFi credentials.
const char* dnshost = "shariqESP"; //copiedota
char ssid[25] = "xxxxxxxx";
char pass[20] = "xxxxxxxxx";
char* mqttServer = "192.168.0.6"; //check actual config of node-red
//const int mqttPort = 1881;
char mqttPort[6] = "1881";
const char* mqttUser = "";
const char* mqttPassword = "";

String mqttServerPref;
String mqttPortPref;

String topicOTA = "ESP/OTAStatus/";
String topicStatus = "ESP/Status/";
String PiStatus = "PiServer/"; //"PiServer/x/Status"
String PiOTAInpStatus = "x/ESP/OTA/";
//String PiRestart ;//"PiServer/x/Status/Restart"

long lastReconnectAttempt = 0;

WiFiClient espClient; //0.4
PubSubClient pubsubclient(espClient);//0.4
Preferences preferences; //v0.5

void cloud_write(uint8_t pin, int pinValue)
{
  Serial.print(pin );
  Serial.print(" " );
  Serial.println(pinValue );
  digitalWrite(pin, pinValue);
  // process received value
}

void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info) {
  Serial.println("Connected to AP successfully!");
}

void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
  Serial.println("Disconnected from WiFi access point");
  Serial.print("WiFi lost connection. Reason: ");
  Serial.println(info.disconnected.reason);
  Serial.println("Trying to Reconnect");
  WiFi.begin(ssid, pass);
  //WiFi.reconnect();
}


void callback(char* topic, byte* payload, unsigned int length) {
 
}

// Utility to extract header value from headers
String getHeaderValue(String header, String headerName) {
  return header.substring(strlen(headerName.c_str()));
}
void saveConfigCallback () {
  Serial.println("saveConfigCallback  fired");

}
void setup() {
Serial.begin(115200);

  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqttServer, 40);
  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqttPort, 5);
  WiFiManagerParameter custom_field; // global param ( for non blocking w params )

  WiFiManager wm;

  wm.setConfigPortalTimeout(40);
  wm.setSaveConfigCallback(saveConfigCallback);

  wm.addParameter(&custom_mqtt_server);
  wm.addParameter(&custom_mqtt_port);
  
  String html_script = "<script>document.getElementById('s').required = true;document.getElementsByName('s')[0].labels[0].innerHTML=document.getElementsByName('s')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";";
  html_script += "document.getElementById('p').required = true;document.getElementsByName('p')[0].labels[0].innerHTML=document.getElementsByName('p')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";";
  html_script += "document.getElementById('server').required = true;document.getElementsByName('server')[0].labels[0].innerHTML=document.getElementsByName('server')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";";
  html_script += "document.getElementById('port').required = true;document.getElementsByName('port')[0].labels[0].innerHTML=document.getElementsByName('port')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";";
  html_script += "</script>";
  
  new (&custom_field) WiFiManagerParameter(html_script.c_str()); // custom html input
  wm.addParameter(&custom_field);

  if (!wm.autoConnect("AutoConnectAP")) {
    Serial.println("failed to connect and hit timeout");
    delay(3000);
 
  }

preferences.begin("MQTTAddress", false);

  if ( strlen(custom_mqtt_server.getValue()) == 0) {
    Serial.println("NO MQTT server not provided,reading from preference");
    mqttServerPref = preferences.getString("mqtt_server", "");
    if (mqttServerPref == "" ) {
      Serial.println("No values saved for mqttServer in Prefences");
    }
    Serial.println( mqttServerPref);
    strcpy(mqttServer , mqttServerPref.c_str());
  
  }

  else if ( strlen(custom_mqtt_server.getValue() ) != 0) {
    //strcpy(mqttServer , (char*)custom_mqtt_server.getValue());
    mqttServer = (char*)custom_mqtt_server.getValue(); //because datatype of mqttServer is char*
    String mqttServerPref = preferences.getString("mqtt_server", "");
    //if (strcmp (mqttServer, mqttServerPref.c_str()  ) != 0) {
      preferences.putString("mqtt_server", custom_mqtt_server.getValue());
      Serial.println("MQTT settings[Server] saved using Preferences");
    //}
  }
//PORT
  if ( strlen( custom_mqtt_port.getValue() )  == 0) {
    Serial.println("NO MQTT port not provided,reading from preference");

    mqttPortPref = preferences.getString("mqtt_port", "");
    if (mqttPortPref == "" ) {
      Serial.println("No values saved for mqttPort in Prefences");
    }
    Serial.println( mqttPortPref);
    strcpy(mqttPort , mqttPortPref.c_str());
  }

  else if ( strlen(custom_mqtt_port.getValue() ) != 0) {
    strcpy(mqttPort , custom_mqtt_port.getValue());
    String mqttPortPref = preferences.getString("mqtt_port", "");

    if (strcmp (mqttPort, mqttPortPref.c_str()  ) != 0) {
      preferences.putString("mqtt_port", custom_mqtt_port.getValue());
      Serial.println("MQTT settings[Port] saved using Preferences");
    }
  }

  preferences.end();

 Serial.print("MQTT IP: ");
  Serial.println(mqttServer);
  Serial.print("MQTT IP: ");
  Serial.println(mqttPort);

 wm.disconnect();
  delay(1000);

  WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_STA_CONNECTED);
  WiFi.onEvent(WiFiGotIP, SYSTEM_EVENT_STA_GOT_IP);
  WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_STA_DISCONNECTED);

  WiFi.begin(ssid, pass);
  Serial.print("main begin ssid:");
  Serial.println(ssid);
  int ct = 0;

  while (WiFi.status() != WL_CONNECTED ) {
    delay(1000);
    ct = ct + 1000;
    if (ct > 5000) {
      Serial.println("not able to connect to wifi");
      break;
    }
  }

InternetStatus = setup_mqtt();


}

bool setup_mqtt() {
  preferences.begin("MQTTAddress", false);
  String mqttServerPref = preferences.getString("mqtt_server", "");
  
  preferences.end();
  long now = millis();
   
  bool connectedBool = false;
  Serial.print("Setting mqtt details: ");
  Serial.print(mqttServer);
  Serial.print(" ");
  Serial.print(mqttServerPref );
  Serial.print(" ");
  Serial.println(atoi(mqttPort));
  
  pubsubclient.setServer(mqttServer, atoi(mqttPort)); 
  pubsubclient.setCallback(callback);
  int  mqct = 0;
   if(pubsubclient.connected()){
    
    return true;
    }
    else{
 while ( (now - lastReconnectAttempt) > 5000 ) {
    lastReconnectAttempt = millis();
    Serial.println("Connecting to MQTT...");
      if (client.connect("ESP32Client")) {
      
      lastReconnectAttempt = 0;
      
      Serial.println("connected");
      //pubsubclient.publish("ESP_Status","ESP device connected ");


      pubsubclient.subscribe(PiStatus.c_str());//"PiServer/x/Status"
      pubsubclient.subscribe(PiOTAInpStatus.c_str());//"PiServer/ESP/OTA/x"
      Serial.print("Trying to publish in ");
      Serial.println(topicStatus.c_str());
 
      connectedBool = true;
      return connectedBool;

    } 
        Serial.print("failed with state ");
      Serial.println(pubsubclient.state());
  
      if (connectedBool) {
        connectedBool = false;
      }
    }
    }
      
   if (!connectedBool) {
        Serial.println("MQTT cannot be reached");
      }

 
  Serial.print("Exiting mqtt details: ");
  Serial.println(mqttServer);
  return connectedBool;
}


void loop() {
if (WiFi.status() != WL_CONNECTED)
  {
  //  digitalWrite(R6, LOW);
    if (DEBUG_SW) Serial.println("Wifi Not Connected");
    delay(400); //custom
    //digitalWrite(R6, HIGH);
    delay(400); //custom

  }
  else
  {
    delay(1000);
    if (DEBUG_SW) Serial.println("Wifi Connected");
    //Serial.print("Heap size after wifi connected: ");
  //Serial.println(ESP.getFreeHeap());
    //reconnect to mqtt or process if incoming string present
    if (pubsubclient.connected()) {
      Serial.println("connected with MQTT");
      //digitalWrite(R6, HIGH);
      pubsubclient.loop();
      InternetStatus =true;

    } else {
      Serial.print("Reconnect to MQTT server failed with state ");
      Serial.println(pubsubclient.state());
      //digitalWrite(R6, LOW);
      InternetStatus = setup_mqtt();

    }

  }
}
#END

Debug Messages

messages here

Additional note if i do strcpy(mqttServer , (char*)custom_mqtt_server.getValue()); instead of mqttServer = (char*)custom_mqtt_server.getValue(); //because datatype of mqttServer is char* it will go into panic mode

Originally created by @shariq-azim on GitHub (Apr 15, 2022). Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1395 #### Hardware WiFimanager Branch/Release: Master Esp32 Hardware: ESP-12e, esp01, esp25 Core Version: 2.4.0, staging ### Description I am trying to set the default value in the custom parameter first, but if there is a change of value i am trying to copy and update another variable that can be re-used as the mqtt server address. So that if the connection is lost it will try to connect again with the last known value. The following code runs one and connects properly during setup but if the connection is lost with MQTT server it wont connect as it would now have garbage value in it. The obvious reason is because the previous value of the pointer is lost after the setup function exists. I have tried so many variations but it is not working ,and unfortunately, the solutions in internet is mostly theory and not the code. Thus, i am reaching for the experts to help. Unfortunately, the solutions in internet is mostly theory and not the code. Please help retrieve the value from a different function. Version :2.03-alpha, 2.0.11 beta Additional libraries: Pubsubclient ### Sketch ```cpp #BEGIN #include <WiFi.h> #include <WiFiClient.h> //#include <WebServer.h> #include <ESPmDNS.h> #include <Update.h> #include <PubSubClient.h>//0.4 //#include <HTTPClient.h> //0.4 #include <ArduinoJson.h> //0.4 // https://github.com/bblanchon/ArduinoJson #include<string.h> //0.4 #include<cstring> //0.4 #include <WiFiManager.h> #include <Preferences.h> bool InternetStatus = false; // Your WiFi credentials. const char* dnshost = "shariqESP"; //copiedota char ssid[25] = "xxxxxxxx"; char pass[20] = "xxxxxxxxx"; char* mqttServer = "192.168.0.6"; //check actual config of node-red //const int mqttPort = 1881; char mqttPort[6] = "1881"; const char* mqttUser = ""; const char* mqttPassword = ""; String mqttServerPref; String mqttPortPref; String topicOTA = "ESP/OTAStatus/"; String topicStatus = "ESP/Status/"; String PiStatus = "PiServer/"; //"PiServer/x/Status" String PiOTAInpStatus = "x/ESP/OTA/"; //String PiRestart ;//"PiServer/x/Status/Restart" long lastReconnectAttempt = 0; WiFiClient espClient; //0.4 PubSubClient pubsubclient(espClient);//0.4 Preferences preferences; //v0.5 void cloud_write(uint8_t pin, int pinValue) { Serial.print(pin ); Serial.print(" " ); Serial.println(pinValue ); digitalWrite(pin, pinValue); // process received value } void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info) { Serial.println("Connected to AP successfully!"); } void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) { Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) { Serial.println("Disconnected from WiFi access point"); Serial.print("WiFi lost connection. Reason: "); Serial.println(info.disconnected.reason); Serial.println("Trying to Reconnect"); WiFi.begin(ssid, pass); //WiFi.reconnect(); } void callback(char* topic, byte* payload, unsigned int length) { } // Utility to extract header value from headers String getHeaderValue(String header, String headerName) { return header.substring(strlen(headerName.c_str())); } void saveConfigCallback () { Serial.println("saveConfigCallback fired"); } void setup() { Serial.begin(115200); WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqttServer, 40); WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqttPort, 5); WiFiManagerParameter custom_field; // global param ( for non blocking w params ) WiFiManager wm; wm.setConfigPortalTimeout(40); wm.setSaveConfigCallback(saveConfigCallback); wm.addParameter(&custom_mqtt_server); wm.addParameter(&custom_mqtt_port); String html_script = "<script>document.getElementById('s').required = true;document.getElementsByName('s')[0].labels[0].innerHTML=document.getElementsByName('s')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";"; html_script += "document.getElementById('p').required = true;document.getElementsByName('p')[0].labels[0].innerHTML=document.getElementsByName('p')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";"; html_script += "document.getElementById('server').required = true;document.getElementsByName('server')[0].labels[0].innerHTML=document.getElementsByName('server')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";"; html_script += "document.getElementById('port').required = true;document.getElementsByName('port')[0].labels[0].innerHTML=document.getElementsByName('port')[0].labels[0].innerHTML +\"<span style='color: red;'>*</span>\";"; html_script += "</script>"; new (&custom_field) WiFiManagerParameter(html_script.c_str()); // custom html input wm.addParameter(&custom_field); if (!wm.autoConnect("AutoConnectAP")) { Serial.println("failed to connect and hit timeout"); delay(3000); } preferences.begin("MQTTAddress", false); if ( strlen(custom_mqtt_server.getValue()) == 0) { Serial.println("NO MQTT server not provided,reading from preference"); mqttServerPref = preferences.getString("mqtt_server", ""); if (mqttServerPref == "" ) { Serial.println("No values saved for mqttServer in Prefences"); } Serial.println( mqttServerPref); strcpy(mqttServer , mqttServerPref.c_str()); } else if ( strlen(custom_mqtt_server.getValue() ) != 0) { //strcpy(mqttServer , (char*)custom_mqtt_server.getValue()); mqttServer = (char*)custom_mqtt_server.getValue(); //because datatype of mqttServer is char* String mqttServerPref = preferences.getString("mqtt_server", ""); //if (strcmp (mqttServer, mqttServerPref.c_str() ) != 0) { preferences.putString("mqtt_server", custom_mqtt_server.getValue()); Serial.println("MQTT settings[Server] saved using Preferences"); //} } //PORT if ( strlen( custom_mqtt_port.getValue() ) == 0) { Serial.println("NO MQTT port not provided,reading from preference"); mqttPortPref = preferences.getString("mqtt_port", ""); if (mqttPortPref == "" ) { Serial.println("No values saved for mqttPort in Prefences"); } Serial.println( mqttPortPref); strcpy(mqttPort , mqttPortPref.c_str()); } else if ( strlen(custom_mqtt_port.getValue() ) != 0) { strcpy(mqttPort , custom_mqtt_port.getValue()); String mqttPortPref = preferences.getString("mqtt_port", ""); if (strcmp (mqttPort, mqttPortPref.c_str() ) != 0) { preferences.putString("mqtt_port", custom_mqtt_port.getValue()); Serial.println("MQTT settings[Port] saved using Preferences"); } } preferences.end(); Serial.print("MQTT IP: "); Serial.println(mqttServer); Serial.print("MQTT IP: "); Serial.println(mqttPort); wm.disconnect(); delay(1000); WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_STA_CONNECTED); WiFi.onEvent(WiFiGotIP, SYSTEM_EVENT_STA_GOT_IP); WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_STA_DISCONNECTED); WiFi.begin(ssid, pass); Serial.print("main begin ssid:"); Serial.println(ssid); int ct = 0; while (WiFi.status() != WL_CONNECTED ) { delay(1000); ct = ct + 1000; if (ct > 5000) { Serial.println("not able to connect to wifi"); break; } } InternetStatus = setup_mqtt(); } bool setup_mqtt() { preferences.begin("MQTTAddress", false); String mqttServerPref = preferences.getString("mqtt_server", ""); preferences.end(); long now = millis(); bool connectedBool = false; Serial.print("Setting mqtt details: "); Serial.print(mqttServer); Serial.print(" "); Serial.print(mqttServerPref ); Serial.print(" "); Serial.println(atoi(mqttPort)); pubsubclient.setServer(mqttServer, atoi(mqttPort)); pubsubclient.setCallback(callback); int mqct = 0; if(pubsubclient.connected()){ return true; } else{ while ( (now - lastReconnectAttempt) > 5000 ) { lastReconnectAttempt = millis(); Serial.println("Connecting to MQTT..."); if (client.connect("ESP32Client")) { lastReconnectAttempt = 0; Serial.println("connected"); //pubsubclient.publish("ESP_Status","ESP device connected "); pubsubclient.subscribe(PiStatus.c_str());//"PiServer/x/Status" pubsubclient.subscribe(PiOTAInpStatus.c_str());//"PiServer/ESP/OTA/x" Serial.print("Trying to publish in "); Serial.println(topicStatus.c_str()); connectedBool = true; return connectedBool; } Serial.print("failed with state "); Serial.println(pubsubclient.state()); if (connectedBool) { connectedBool = false; } } } if (!connectedBool) { Serial.println("MQTT cannot be reached"); } Serial.print("Exiting mqtt details: "); Serial.println(mqttServer); return connectedBool; } void loop() { if (WiFi.status() != WL_CONNECTED) { // digitalWrite(R6, LOW); if (DEBUG_SW) Serial.println("Wifi Not Connected"); delay(400); //custom //digitalWrite(R6, HIGH); delay(400); //custom } else { delay(1000); if (DEBUG_SW) Serial.println("Wifi Connected"); //Serial.print("Heap size after wifi connected: "); //Serial.println(ESP.getFreeHeap()); //reconnect to mqtt or process if incoming string present if (pubsubclient.connected()) { Serial.println("connected with MQTT"); //digitalWrite(R6, HIGH); pubsubclient.loop(); InternetStatus =true; } else { Serial.print("Reconnect to MQTT server failed with state "); Serial.println(pubsubclient.state()); //digitalWrite(R6, LOW); InternetStatus = setup_mqtt(); } } } #END ``` ### Debug Messages ``` messages here ``` Additional note if i do strcpy(mqttServer , (char*)custom_mqtt_server.getValue()); instead of mqttServer = (char*)custom_mqtt_server.getValue(); //because datatype of mqttServer is char* it will go into panic mode
kerem 2026-02-28 01:28:57 +03:00
  • closed this issue
  • added the
    Question
    label
Author
Owner

@tablatronix commented on GitHub (Apr 15, 2022):

hmm would think you would have to use a global char[] array and either set its size ahead of time, or dynamically allocate it , or just use a Strings

<!-- gh-comment-id:1100286666 --> @tablatronix commented on GitHub (Apr 15, 2022): hmm would think you would have to use a global char[] array and either set its size ahead of time, or dynamically allocate it , or just use a Strings
Author
Owner

@shariq-azim commented on GitHub (Apr 15, 2022):

hmm would think you would have to use a global char[] array and either set its size ahead of time, or dynamically allocate it , or just use a Strings

Good day to you.

I dont think pubsubclient.setserver accepts either char[] or string as an input parameter?

<!-- gh-comment-id:1100315082 --> @shariq-azim commented on GitHub (Apr 15, 2022): > hmm would think you would have to use a global char[] array and either set its size ahead of time, or dynamically allocate it , or just use a Strings Good day to you. I dont think pubsubclient.setserver accepts either char[] or string as an input parameter?
Author
Owner

@shariq-azim commented on GitHub (Apr 17, 2022):

hmm would think you would have to use a global char[] array and either set its size ahead of time, or dynamically allocate it , or just use a Strings

hello @tablatronix , i was just wondering if it is possible to set the value into a global variable from custom_mqtt_server.getValue() so that it can be used at later point? the step you provided earlier somehow didnt work for me..

<!-- gh-comment-id:1100896222 --> @shariq-azim commented on GitHub (Apr 17, 2022): > hmm would think you would have to use a global char[] array and either set its size ahead of time, or dynamically allocate it , or just use a Strings hello @tablatronix , i was just wondering if it is possible to set the value into a global variable from custom_mqtt_server.getValue() so that it can be used at later point? the step you provided earlier somehow didnt work for me..
Author
Owner

@tablatronix commented on GitHub (Apr 17, 2022):

you can do something like the example

char mqtt_server[40];
strcpy(mqtt_server, custom_mqtt_server.getValue());

<!-- gh-comment-id:1100926158 --> @tablatronix commented on GitHub (Apr 17, 2022): you can do something like the example char mqtt_server[40]; strcpy(mqtt_server, custom_mqtt_server.getValue());
Author
Owner

@shariq-azim commented on GitHub (Apr 19, 2022):

Thank you .it worked

<!-- gh-comment-id:1101940306 --> @shariq-azim commented on GitHub (Apr 19, 2022): Thank you .it worked
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#1195
No description provided.