Craigfoo
Craigfoo

Reputation: 323

Create a New Object in a Function - C++

I'm using a library for an MQTT connection and I would like to make a function that creates the object instead of setting it up in the pre-processor. The reason is because I need to grab which server it connects to after the program starts running.

Here is my mqttConnection function:

void mqttConnection(bool checkConnection)   {

if (!checkConnection)   {
    strcpy(mqttServer, mqttUrl);

    PubSubClient client(mqttServer, 1883, callback, wifiClient); // why would it care if this was here?
}

// Connecting to MQTT broker, loop until connected
while (!client.connected()){
    if(!client.connect("device-name")) {
        Serial.println("MQTT Broker Connection Failed. Trying Again...");
    }
    else {
        Serial.println("MQTT Broker Connection Success!");
        if(client.subscribe(mqttTopic)) {
            Serial.println("Subscription Successful! Woot!");
        }
    }
}

}

Here is the Class:

#ifndef PubSubClient_h
#define PubSubClient_h

#include <Arduino.h>
#include "Client.h"

// MQTT_MAX_PACKET_SIZE : Maximum packet size
#define MQTT_MAX_PACKET_SIZE 128

// MQTT_KEEPALIVE : keepAlive interval in Seconds
#define MQTT_KEEPALIVE 15

#define MQTTPROTOCOLVERSION 3
#define MQTTCONNECT     1 << 4  // Client request to connect to Server
#define MQTTCONNACK     2 << 4  // Connect Acknowledgment
#define MQTTPUBLISH     3 << 4  // Publish message
#define MQTTPUBACK      4 << 4  // Publish Acknowledgment
#define MQTTPUBREC      5 << 4  // Publish Received (assured delivery part 1)
#define MQTTPUBREL      6 << 4  // Publish Release (assured delivery part 2)
#define MQTTPUBCOMP     7 << 4  // Publish Complete (assured delivery part 3)
#define MQTTSUBSCRIBE   8 << 4  // Client Subscribe request
#define MQTTSUBACK      9 << 4  // Subscribe Acknowledgment
#define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request
#define MQTTUNSUBACK    11 << 4 // Unsubscribe Acknowledgment
#define MQTTPINGREQ     12 << 4 // PING Request
#define MQTTPINGRESP    13 << 4 // PING Response
#define MQTTDISCONNECT  14 << 4 // Client is Disconnecting
#define MQTTReserved    15 << 4 // Reserved

#define MQTTQOS0        (0 << 1)
#define MQTTQOS1        (1 << 1)
#define MQTTQOS2        (2 << 1)

class PubSubClient {
private:
   Client* _client;
   uint8_t buffer[MQTT_MAX_PACKET_SIZE];
   uint16_t nextMsgId;
   unsigned long lastOutActivity;
   unsigned long lastInActivity;
   bool pingOutstanding;
   void (*callback)(char*,uint8_t*,unsigned int);
   uint16_t readPacket();
   uint8_t readByte();
   boolean write(uint8_t header, uint8_t* buf, uint16_t length);
   uint16_t writeString(char* string, uint8_t* buf, uint16_t pos);
   uint8_t *ip;
   char* domain;
   uint16_t port;
public:
   PubSubClient(Client& client);
   PubSubClient(uint8_t *, uint16_t, void(*)(char*,uint8_t*,unsigned int),Client& client);
   PubSubClient(char*, uint16_t, void(*)(char*,uint8_t*,unsigned int),Client& client);
   boolean connect(char *);
   boolean connect(char *, char *, char *);
   boolean connect(char *, char *, uint8_t, uint8_t, char *);
   boolean connect(char *, char *, char *, char *, uint8_t, uint8_t, char*);
   void disconnect();
   boolean publish(char *, char *);
   boolean publish(char *, uint8_t *, unsigned int);
   boolean publish(char *, uint8_t *, unsigned int, boolean);
   boolean publish_P(char *, uint8_t *, unsigned int, boolean);
   boolean subscribe(char *);
   boolean loop();
   boolean connected();
};


#endif

The error I get is,

'client' was not declared in this scope

Why does it matter that it's in the function?

Upvotes: 0

Views: 598

Answers (4)

I_am_Manu
I_am_Manu

Reputation: 11

i can connect with mQTT server and also i can subscribe from client. but how to get subscribed data from client

it shows 1

str=client.subscribe(testq);
   if(str>0)
    {

       Serial.println(str);
}

which means subscription successfull

but how to print subscribed data

KIndly Help me

Upvotes: 0

knolleary
knolleary

Reputation: 10117

In addition to the answers regarding the scope of client, if you use the latest version of the PubSubClient library, there are now functions for setting the server details after the client object has been created:

PubSubClient client(wifiClient);

// some time later
client.setServer(mqttServer,1883);

This makes it much easier to change the server details at runtime.

Full api documentation is available here: http://pubsubclient.knolleary.net/

Upvotes: 3

Carlton
Carlton

Reputation: 4297

The scope of client is limited to the if statement. You need to move its declaration outside of that scope, like this:

PubSubClient client(/*Some default arguments*/);

if (!checkConnection) {
   client = client(mqttServer, 1883, callback, wifiClient);
}

while (!client.connected()) {
/*...*/
}

Upvotes: 2

NathanOliver
NathanOliver

Reputation: 180415

PubSubClient client(mqttServer, 1883, callback, wifiClient);

Is inside an if statement scope. Because of the scope rules in C++ the variable can only be accessed until the closing brace of the if statement.

You can change

if (!checkConnection) {
    strcpy(mqttServer, mqttUrl);

    PubSubClient client(mqttServer, 1883, callback, wifiClient); // why would it care if this was here?
}

To

if (!checkConnection) {
    strcpy(mqttServer, mqttUrl);
}
PubSubClient client(mqttServer, 1883, callback, wifiClient);

Upvotes: 3

Related Questions