Error Connection failed
thesun93pp opened this issue · comments
Adafruit_MQTT library is awesome but i have got a problem with it.
I use it in Arduino with NodeMCU (ESP8266).
Everything is okey with example code. (TLS connection).
Everything is also ok when i put topic direct value: "sometopic/abc/adbc" to input param.
//Connect successfuly when i use:
GLB_MQTTClient = temMQTT;
Adafruit_MQTT_Publish *temPub = new Adafruit_MQTT_Publish(GLB_MQTTClient, "pubTopic", MQTT_QOS_1);
Adafruit_MQTT_Subscribe *temSub = new Adafruit_MQTT_Subscribe(GLB_MQTTClient, "subTopic", MQTT_QOS_1);
But My program has to check some configs to get MQTT topic from EEPROM so it can't assign TOPIC when initialize variable at head of file.
So i created new pointer for new value.
I got Connection failed when i use
This is my basic code:
WiFiClientSecure GLB_secureClient;
//Init with default value, cuz the library does not have default constructor
Adafruit_MQTT_Client *GLB_MQTTClient = new Adafruit_MQTT_Client(NULL, NULL, NULL, NULL, NULL, NULL);
Adafruit_MQTT_Publish *GLB_MQTT_Publish = new Adafruit_MQTT_Publish(NULL, NULL, MQTT_QOS_1);
Adafruit_MQTT_Subscribe *GLB_MQTT_Subcribe = new Adafruit_MQTT_Subscribe(NULL,NULL,MQTT_QOS_1);
void initNormalConnection()
{
printf("\n\nAddress of GLB_secureClient: %p\n", &GLB_secureClient);
printf("Address of GLB_MQTTClient: %p\n", GLB_MQTTClient);
printf("Address of GLB_MQTT_Publish: %p\n", GLB_MQTT_Publish);
printf("Address of GLB_MQTT_Subcribe: %p\n", GLB_MQTT_Subcribe);
GLB_secureClient = WiFiClientSecure();
GLB_secureClient.setFingerprint(FINGER_PRINT);
Adafruit_MQTT_Client *temMQTT = new Adafruit_MQTT_Client(&GLB_secureClient, BROKER_HOST, BROKER_PORT);
GLB_MQTTClient = temMQTT;
Adafruit_MQTT_Publish *temPub = new Adafruit_MQTT_Publish(GLB_MQTTClient, pubTopic, MQTT_QOS_1);
Adafruit_MQTT_Subscribe *temSub = new Adafruit_MQTT_Subscribe(GLB_MQTTClient, subTopic, MQTT_QOS_1);
GLB_MQTT_Publish = temPub;
GLB_MQTT_Subcribe = temSub;
GLB_MQTT_Subcribe->setCallback(MQTTCtrCallback);
GLB_MQTTClient->subscribe(GLB_MQTT_Subcribe);
printf("\n\nAddress of GLB_secureClient: %p\n", &GLB_secureClient);
printf("Address of GLB_MQTTClient: %p\n", GLB_MQTTClient);
printf("Address of GLB_MQTT_Publish: %p\n", GLB_MQTT_Publish);
printf("Address of GLB_MQTT_Subcribe: %p\n", GLB_MQTT_Subcribe);
PRINTLN("\ninitNormalConnection");
}
void MQTTConnect()
{
int8_t ret;
// Stop if already connected.
PRINTLN("MQTTConnect");
if (GLB_MQTTClient->connected())
{
PRINTLN("connected");
return;
}
PRINTLN("not connected");
if (stateSmartConfig || WiFi.status() != WL_CONNECTED)
{
return;
}
PRINTLN("Connecting to MQTT... ");
uint8_t retries = 3;
ret = GLB_MQTTClient->connect();
PRINT("Connect MQTT result: ");
PRINTLN(ret);
while (ret != 0)
{ // connect will return 0 for connected
ERR_PRINTLN(GLB_MQTTClient->connectErrorString(ret));
DEBUG_PRINTLN("Retrying MQTT connection in 10 seconds...");
GLB_MQTTClient->disconnect();
delay(10000);
retries--;
if (retries == 0)
{
// basically die and wait for WDT to reset me
return;
}
}
Serial.println("MQTT Connected!");
}
void setup(){
initNormalConnection();
}
void loop()
{
//do somethings
MQTTConnect();
GLB_MQTTClient->processPackets(10000);
if (!GLB_MQTTClient->ping())
{
GLB_MQTTClient->disconnect();
}
}
Variable's addresses was changed.
The output of the address:
Address of GLB_secureClient: 0x3ffef170
Address of GLB_MQTTClient: 0x3fff167c
Address of GLB_MQTT_Publish: 0x3fff17e4
Address of GLB_MQTT_Subcribe: 0x3fff17f4Address of GLB_secureClient: 0x3ffef170
Address of GLB_MQTTClient: 0x3fff27ac
Address of GLB_MQTT_Publish: 0x3fff220c
Address of GLB_MQTT_Subcribe: 0x3fff2914
What could be the problem?
In the Adafruit_MQTT.h header file, could you please uncomment MQTT_DEBUG.
Do not post the output from serial here, but you could probably guess more about your problem with it
I have an idea
extend the library
the problem is when you declare before setup is can't change the value.
what you need to save into/load from eeprom in my point of view is
username, key and feeds
see the source code in https://github.com/adafruit/Adafruit_MQTT_Library/blob/master/examples/mqtt_esp8266/mqtt_esp8266.ino
in declarative part
put the server object definition without username and key
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT);
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
in setup()
you can set username and key through connect() public method, which is you can retrieve from eeprom
//retreive username and key from eeprom
//example 0 - 19 is username, 20 - 79 is key
String usern ,keyn;
char username[21], key[61];
for (int i = 0; i < 20; i++)
{
username[i] = EEPROM.read(i);
i++;
}
// put null as end of string
username[20]='\0';
for (int i = 20; i < 80; i++)
{
key[i-20] = EEPROM.read(i);
i++;
}
key[60]='\0';
usern = String(username);
keyn = String(key);
const char *usernew = usern.c_str();
const char *keynew = keyn.c_str();
mqtt.connect(usernew, keynew);
next to make feeds become changeable on setup()
u need to add method on Adafruit_MQTT.h and Adafruit_MQTT.cpp
open header first
add on line 280
class Adafruit_MQTT_Subscribe {
273 public:
274 Adafruit_MQTT_Subscribe(Adafruit_MQTT *mqttserver, const char *feedname, uint8_t q=0);
275
276 void setCallback(SubscribeCallbackUInt32Type callb);
277 void setCallback(SubscribeCallbackDoubleType callb);
278 void setCallback(SubscribeCallbackBufferType callb);
279 void setCallback(AdafruitIO_MQTT *io, SubscribeCallbackIOType callb);
*280 void setFeeds(const char feed);
open cpp
add at the end of file
void Adafruit_MQTT_Subscribe::setFeeds(const char *feed) {
topic = feed;
}
now in your setup() before mqtt.connect(usernew, keynew);
set subscribe feeds
feedsnew you can do same with usernew
onoffbutton.setFeeds(feedsnew);
you can do same with subscribe for publish part.
let's make apps with more flexible
You are misunderstanding how to use heap. You instantiate GLB_MQTTClient, GLB_MQTT_Publish, GLB_MQTT_Subcribe twice on a heap, and so you have small memory leak, you lost pointers to classes instatiated in declarative section. For the first declare only a pointers and then instantiate an object in a initNormalConnection().
code excerpt:
`WiFiClientSecure GLB_secureClient;
//Init with default value, cuz the library does not have default constructor
Adafruit_MQTT_Client *GLB_MQTTClient;
Adafruit_MQTT_Publish *GLB_MQTT_Publish;
Adafruit_MQTT_Subscribe *GLB_MQTT_Subcribe;
void initNormalConnection()
{
printf("\n\nAddress of GLB_secureClient: %p\n", &GLB_secureClient);
printf("Address of GLB_MQTTClient: %p\n", GLB_MQTTClient);
printf("Address of GLB_MQTT_Publish: %p\n", GLB_MQTT_Publish);
printf("Address of GLB_MQTT_Subcribe: %p\n", GLB_MQTT_Subcribe);
GLB_secureClient = WiFiClientSecure();
GLB_secureClient.setFingerprint(FINGER_PRINT);
GLB_MQTTClient = new Adafruit_MQTT_Client(&GLB_secureClient, BROKER_HOST, BROKER_PORT);
GLB_MQTT_Publish = new Adafruit_MQTT_Publish(GLB_MQTTClient, pubTopic, MQTT_QOS_1);
GLB_MQTT_Subcribe = new Adafruit_MQTT_Subscribe(GLB_MQTTClient, subTopic, MQTT_QOS_1);
...`