Establishing MQTT Connection

I've been out of the scene for quite some time for personal reasons. Trying to get back into things that make me happy. I need help with this sketch. I think the errors may be due to changes in the IDE. Pretty sure it was working fine before.
@PaulRB, @pert
In this sketch just want to connect to the wifi and mqtt server.

/*
Connect Lolin ESP8266-Pro to Mosquitto MQTT on Raspberry Pi3(b)

Nick Sebring
04-27-2025

*/

//#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
//#include <Wire.h>
#include <SPI.h>


// Connect to the WiFi
const char* ssid = "mySSID";
const char* password = "myPASSWORD";
const char* mqtt_server = "192.168.#.###";

WiFiClient espClient;
PubSubClient client(espClient);



boolean reconnect() {  // **********************************************************
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print (F("Contacting MQTT server..."));
    // Attempt to connect
    if (client.connect("BME280")) {     //assign a "client name".  Each wemos must have a unique name
      Serial.println (F("connected"));

      // ... SUBSCRIBE TO TOPICS
      //      client.subscribe("Upsatairs/Mbr/BME280/TempF");
      //      client.subscribe("Upstairs/Mbr/BME280/TempC");
      //      client.subscribe("Upstairs/Mbr/BME280/Humidity");
      //      client.subscribe("Upstairs/Mbr/BME280/Pressure");

      return client.connected();

      Serial.print (F("Failed to connect. "));
      Serial.println (F(" Attempting connection again in 3 seconds"));
      // Wait 3 seconds before retrying
      //      delay(3000);
      return 0;
    }
  }
}


void setup()
{
  {
    Serial.begin(9600);
    client.setServer(mqtt_server, 1883);
  }

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print (F("Connecting to "));
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    //Serial.begin(9600);
    Serial.print (F("."));
  }
  Serial.println (F(""));
  Serial.println (F("WiFi connected"));
  // Print the IP address
  Serial.print (F("Local IP: "));
  Serial.println(WiFi.localIP());


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

  client.loop();
}

Errors:

C:\Users\marin\OneDrive\Documents\Arduino\MQTT_Connect\MQTT_Connect.ino: In function 'void setup()':
C:\Users\marin\OneDrive\Documents\Arduino\MQTT_Connect\MQTT_Connect.ino:82:12: error: a function-definition is not allowed here before '{' token
   82 | void loop(){
      |            ^
C:\Users\marin\OneDrive\Documents\Arduino\MQTT_Connect\MQTT_Connect.ino:88:1: error: expected '}' at end of input
   88 | }
      | ^
C:\Users\marin\OneDrive\Documents\Arduino\MQTT_Connect\MQTT_Connect.ino:54:1: note: to match this '{'
   54 | {
      | ^
C:\Users\marin\OneDrive\Documents\Arduino\MQTT_Connect\MQTT_Connect.ino: In function 'boolean reconnect()':
C:\Users\marin\OneDrive\Documents\Arduino\MQTT_Connect\MQTT_Connect.ino:50:1: error: control reaches end of non-void function [-Werror=return-type]
   50 | }
      | ^
cc1plus.exe: some warnings being treated as errors
exit status 1

Compilation error: a function-definition is not allowed here before '{' token

That sketch never worked as it is now presented, and the problems have nothing to do with the IDE.

A simple auto formatting starting with the setup() function reveals that you are missing the closing } for the setup() function, and the loop() function is now embedded within the setup() function, which is obviously incorrect.

void setup() {
   {
      Serial.begin(9600);
      client.setServer(mqtt_server, 1883);
   }

   // Connect to WiFi network
   Serial.println();
   Serial.println();
   Serial.print(F("Connecting to "));
   Serial.println(ssid);

   WiFi.begin(ssid, password);
   WiFi.mode(WIFI_STA);
   while( WiFi.status() != WL_CONNECTED ) {
      delay(500);
      //Serial.begin(9600);
      Serial.print(F("."));
   }
   Serial.println(F(""));
   Serial.println(F("WiFi connected"));
   // Print the IP address
   Serial.print(F("Local IP: "));
   Serial.println(WiFi.localIP());


   //  *********************************************************************************

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

      client.loop();
   }

The problem has nothing to do with changes in the IDE

Take a close look at the setup() function in the sketch. Ask yourself why the function has two opening braces

Here is your sketch after Auto formatting it in the IDE which makes the code blocks more obvious

/*
Connect Lolin ESP8266-Pro to Mosquitto MQTT on Raspberry Pi3(b)

Nick Sebring
04-27-2025

*/

//#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
//#include <Wire.h>
#include <SPI.h>

// Connect to the WiFi
const char* ssid = "mySSID";
const char* password = "myPASSWORD";
const char* mqtt_server = "192.168.#.###";

WiFiClient espClient;
PubSubClient client(espClient);

boolean reconnect()
{  // **********************************************************
    // Loop until we're reconnected
    while (!client.connected())
    {
        Serial.print(F("Contacting MQTT server..."));
        // Attempt to connect
        if (client.connect("BME280"))
        {  //assign a "client name".  Each wemos must have a unique name
            Serial.println(F("connected"));

            // ... SUBSCRIBE TO TOPICS
            //      client.subscribe("Upsatairs/Mbr/BME280/TempF");
            //      client.subscribe("Upstairs/Mbr/BME280/TempC");
            //      client.subscribe("Upstairs/Mbr/BME280/Humidity");
            //      client.subscribe("Upstairs/Mbr/BME280/Pressure");

            return client.connected();

            Serial.print(F("Failed to connect. "));
            Serial.println(F(" Attempting connection again in 3 seconds"));
            // Wait 3 seconds before retrying
            //      delay(3000);
            return 0;
        }
    }
}

void setup()
{
    {
        Serial.begin(9600);
        client.setServer(mqtt_server, 1883);
    }

    // Connect to WiFi network
    Serial.println();
    Serial.println();
    Serial.print(F("Connecting to "));
    Serial.println(ssid);

    WiFi.begin(ssid, password);
    WiFi.mode(WIFI_STA);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        //Serial.begin(9600);
        Serial.print(F("."));
    }
    Serial.println(F(""));
    Serial.println(F("WiFi connected"));
    // Print the IP address
    Serial.print(F("Local IP: "));
    Serial.println(WiFi.localIP());

    //  *********************************************************************************

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

        client.loop();
    }

There's at least one missing } between these two lines.

Also missing a return in the reconnect function.

And it looks like an extra return. Somehow your code got rearranged. Check that reconnect closely.

Here we go!!!

/*
 * MQTT Connection
 * By Nick Sebring
 * 04-28-2025
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

WiFiClient mqttClient;
PubSubClient client(mqttClient);


const char* ssid = "MySSID";
const char* password = "MyPassword";
const char* mqtt_server = "192.168.#.###";

void setup_wifi() {
  int i = 0;
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");  // We start by connecting to a WiFi network
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    i++;
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("WiFi connected");
  Serial.print("Client IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  while (!client.connected()) {  // Loop until we're connected
    Serial.println("Connecting to MQTT broker...");
    String clientId = "anything";  // eACH CLIENT MUST HAVE A UNIQUE NAME


    if (client.connect(clientId.c_str())) {  // Attempt to connect
      Serial.println("connected");
      //client.subscribe("Remote/Relay");      // ... and resubscribe
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);  // Wait 5 seconds before retrying
    }
  }
}

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  //  client.setCallback(callback);
}

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


  // DO SOMETHING
  // GET SENSOR DATA
  client.publish("Outside/Temp", "140");  // sOMETHING LIKE THIS
  delay(600000);                          // Report sensor data every 10 minutes
}

Better?
The callback is only needed when subscribing to a topic and polling the mqtt server for an update?

@marine_hm_again if the abovementioned issues with your presented code resulted from multiple cut-and-pastes not accurately getting the whole thing, please be aware that there is a command in the IDE, "copy for forum", that makes posting your code accurately a painless action. Please use it in future.

1 Like

Ctrl Shift C
Got it. THANKS!

1 Like

For extra brownie points use Auto format in the IDE
(Ctrl+T) before copying the code

1 Like

I've made several iterations and got the callback working. It may not be proper but, it works. :grinning_face:

I know I have it called "relayPin" but for now, I have an LED in it's place, just to see it work before putting to use

the LED connected to D5 on the Wemos D1 mini Pro remains ON no matter what.
What am I missing?


/*
 * My info here
 */

#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>


// Connect to the WiFi
const char* ssid = "MySSID";
const char* password = "MyPassword";
const char* mqtt_server = "192.168.#.###";

WiFiClient espClient;
PubSubClient client(espClient);
const int relayPin = D5;  // LED atttached to Wemos D5 Mini Pro (GPIO14)

// pinMode(relayPin, OUTPUT);
// ******************* REMOTE RELAY *****************************
void callback(char* topic, byte* payload, unsigned int length) {
  pinMode(relayPin, OUTPUT);
  if (strcmp(topic, "Remote/Relay") == 0) {

    for (int i = 0; i < length; i++) {
      char receivedChar = (char)payload[i];
      if (receivedChar == '0') {
        Serial.println(F("Remote Relay OFF"));
        digitalWrite(relayPin, HIGH);
      }
      if (receivedChar == '1') {
        Serial.println(F("Remote Relay ON"));
        digitalWrite(relayPin, LOW);
      }
    }
  }
}


void reconnect() {  // **********************************************************
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print(F("Contacting MQTT server..."));
    // Attempt to connect
    if (client.connect("Relay42")) {  //assign a "client name".  Each wemos must have a unique name
      Serial.println(F("connected"));
      // ... SUBSCRIBE TO TOPICS
      client.subscribe("Remote/Relay");
      //      return client.connected();
    } else {
      Serial.print(F("Failed to connect. "));
      Serial.println(F(" Attempting connection again in 3 seconds"));
      // Wait 3 seconds before retrying
      delay(3000);
      //digitalWrite(relayPin, LOW);
    }
  }
}

void setup() {
  {
    Serial.begin(9600);
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    //    pinMode(relayPin, OUTPUT);
  }


  // Connect to WiFinetwork
  Serial.println();
  Serial.println();
  Serial.print(F("Connecting to "));
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    //Serial.begin(9600);
    Serial.print(F("."));
  }
  Serial.println(F(""));
  Serial.println(F("WiFi connected"));
  // Print the IP address
  Serial.print(F("Local IP: "));
  Serial.println(WiFi.localIP());
}


void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.publish("Outside/Temp", "140");  // Something like this


  //  delay(5000);  // Report sensor data every 5 seconds
  client.loop();
}

Start by taking the pinMode() for relayPin out of callback() and put it in setup)_ where it belongs.

What exactly are you receiving as the payload ?
How long is it ?
How is the LED wired ?
Does it have current limiting resistor in series ?

1st of all.... Thank you for helping me understand.

Payload is 1 or 0
The LED is attached to pin D4 of a LOLIN ESP8266 D1 Mini Pro with (4k?) resistor in between ESP and LED.

I get a printout in the serial monitor that it connects and displays the text:

Contacting MQTT server...connected
Remote Relay ON
Remote Relay OFF

as I send the message via MQTT console on the Raspberry Pi3b

LED remains lit


```cpp
/*
 * My info here
 */

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Connect to the WiFi
const char* ssid = "MySSID";
const char* password = "Mypassword";
const char* mqtt_server = "192.168.#.###";

WiFiClient espClient;
PubSubClient client(espClient);
const int relayPin = D5;  // LED atttached to Wemos D5 Mini Pro (GPIO14)



// ******************* REMOTE RELAY *****************************
void callback(char* topic, byte* payload, unsigned int length) {
  //  pinMode(relayPin, OUTPUT);
  //digitalWrite(relayPin, LOW);
  if (strcmp(topic, "Remote/Relay") == 0) {

    for (int i = 0; i < length; i++) {
      char receivedChar = (char)payload[i];
      if (receivedChar == '0') {
        Serial.println(F("Remote Relay OFF"));
        digitalWrite(relayPin, LOW);
      }
      if (receivedChar == '1') {
        Serial.println(F("Remote Relay ON"));
        digitalWrite(relayPin, HIGH);
      }
    }
  }
}


void reconnect() {  // **********************************************************
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print(F("Contacting MQTT server..."));
    // Attempt to connect

    if (client.connect("Relay420")) {  //assign a "client name".  Each wemos must have a unique name
      Serial.println(F("connected"));
      //digitalWrite(relayPin, LOW);

      // ... SUBSCRIBE TO TOPICS
      client.subscribe("Remote/Relay");

    } else {
      Serial.print(F("Failed to connect. "));
      Serial.println(F(" Attempting connection again in 3 seconds"));
      // Wait 3 seconds before retrying
      delay(3000);
      //digitalWrite(relayPin, LOW);
    }
  }
}

void setup() {
  {
    Serial.begin(9600);
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    pinMode(relayPin, OUTPUT);
    digitalWrite(relayPin, LOW);  //  Turn off LED at startup
  }


  // Connect to WiFinetwork
  Serial.println();
  Serial.println();
  Serial.print(F("Connecting to "));
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println(F(""));
  Serial.println(F("WiFi connected"));
  // Print the IP address
  Serial.print(F("Local IP: "));
  Serial.println(WiFi.localIP());
}


void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.publish("Outside/Temp", "140");  // Something like this


  //  delay(5000);  // Report sensor data every 5 seconds
  client.loop();
}

If the payload is 0 or 1 then why read its contents with a for loop ?

Exactly what is being sent, ie what data type, how many bytes and is the payload terminated with a line ending ?
What is the length of the payload received by the Arduino ?

Working!

Changed:
const int relayPin = D0; // LED atttached to Wemos D0 Mini Pro (GPIO16)

To:
const int relayPin = 0; // LED atttached to Wemos D0 Mini Pro (GPIO16)

Completed sketch:

/*
 * MQTT connection using LOLIN ESP8266 D1 Mini Pro
 * Connects to WiFi, then MQTT broker (running on Raspberry Pi)
 * Subscribes to an MQTT topic
 * Publishes an MQTT topic
 * 
* Created by Nick Sebring
* 05-03-2025
 */

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Connect to the WiFi
const char* ssid = "My SSID";
const char* password = "My password";
const char* mqtt_server = "192.168.#.###";

WiFiClient espClient;
PubSubClient client(espClient);

const int relayPin = 0;  // LED atttached to Wemos D0 Mini Pro (GPIO16)



// ******************* REMOTE RELAY *****************************
void callback(char* topic, byte* payload, unsigned int length) {
  if (strcmp(topic, "Remote/Relay") == 0) {
    for (int i = 0; i < length; i++) {
      char receivedChar = (char)payload[i];
      if (receivedChar == '0') {
        digitalWrite(relayPin, LOW);
        Serial.println(F("Remote Relay OFF"));
      }
      if (receivedChar == '1') {
        digitalWrite(relayPin, HIGH);
        Serial.println(F("Remote Relay ON"));
      }
    }
  }
}


void reconnect() {  // **********************************************************
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print(F("Contacting MQTT server..."));
    // Attempt to connect
    if (client.connect("Relay420")) {  //assign a "client name".  Each wemos must have a unique name
      Serial.println(F("connected"));

      // ... SUBSCRIBE TO TOPICS
      client.subscribe("Remote/Relay");

    } else {
      Serial.print(F("Failed to connect. "));
      Serial.println(F(" Attempting connection again in 3 seconds"));
      // Wait 3 seconds before retrying
      delay(3000);
    }
  }
}

void setup() {
  {
    Serial.begin(9600);
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    pinMode(relayPin, OUTPUT);
    digitalWrite(relayPin, LOW);  //  Turn off LED at startup
  }


  // Connect to WiFinetwork
  Serial.println();
  Serial.println();
  Serial.print(F("Connecting to "));
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println(F(""));
  Serial.println(F("WiFi connected"));
  // Print the IP address
  Serial.print(F("Local IP: "));
  Serial.println(WiFi.localIP());
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.publish("Outside/Temp", "140");  // Something like this


  //  delay(5000);  // Report sensor data every 5 seconds
  client.loop();
}

Now, to work on the "DO SOMETHING" in the LOOP.

I would still be interested in answers to my questions in post #15

I'm pretty sure that was for my sketch that had multiple subscribed topics.
IE..
if (strcmp(topic, "Remote/Relay1") == 0) {
if (strcmp(topic, "Remote/Relay2") == 0) {
if (strcmp(topic, "Remote/Relay3") == 0) {

If you're talking about:
for (int i = 0; i < length; i++) {

Honestly, I don't remember. Bits and pieces I had help with. NO, I had help with quite a bit.

Sometimes, I miss a curly bracket, and I'm totally hosed!