top of page

NodeMCU Callback-Subscribe



In our previous examples, we published data from nodemcu to our software.


Now we will explain how to use the data published from our software in nodemcu.


MQTT and wifi connection codes are the same as in our previous examples.


The message format published from our software to nodemcu is also the same.

Device name / data name / data value


Nodemcu must be subscribed to receive messages.


In order to receive messages published under his own name, we will subscribe to incoming messages under his own name.We should use subscribe operations within mqtt connection and reconnection blocks.

To subscribe we will use the following line of code for each data.



client.subscribe("devicename/topic");


We will use the callback function to use the data when the subscribed message is received.We're going to shred the incoming message.We should use this command in MQTT connection and reconnection blocks.



client.setCallback(callback);

Let's define our variables



String Topik; //Our variable that we will use for comparison by keeping the tags/topic information from mqtt 
String data_value; // our variable to hold the message information
char message_store[100]; // variable to save the incoming message as a character 

Our callback function will be as follows.


void callback(char* topic, byte* payload, unsigned int length) { // Let's get the incoming topic-tag information and message 
 int i = 0;
 Serial.println("message received");
 Serial.println(topic); // Let's print the incoming topic-tag information to the serial port 
   Topik = String (topic); // write it to our variable to use the incoming topic information 
  Serial.print("incomming message:");
  for (i = 0; i < length; i++) {
 Serial.print((char)payload[i]); // write the incoming message to the serial port 
    message_store[i] = ((char)payload[i]); // store the incoming characters as characters in the message store 
  }
  message_store[i] = '\0'; // find the end of the message 

// Now let's find our data from the incoming message 

 if (Topik == "devicename/topic"){
  data_value = (message_store);
 }
 
}


Now let's make the system that will send the value of 500 with the number topic i to the device named nodemcu1.

Let Nodemcu send the data it receives back to our system with the name of numberresend.


Subscirbe message

Device name : nodemcu1

Topic : number

client.subscribe("nodemcu1/number");

Publish message

Device name : nodemcu1

Topic : numberresend


client.publish("nodemcu1/numberresend", String(data_value).c_str());

We can make our system more stable by using milis command instead of delay command.Below is the program block that will send a message every two seconds.



  unsigned long previousMillis;
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= 2000) {
    client.publish("nodemcu1/numberresend", String(data_value).c_str());// send our message in the topic with the device name
    Serial.println("message send");
   previousMillis = currentMillis; 
  }

Our main program has been created.You can expand your system by adding as many variables as you want in this program.





#include <ESP8266WiFi.h> //The library we will use for the wifi connection
#include <PubSubClient.h> // The library we will use for the mqtt connection

//mqtt connection library settings
WiFiClient espClient;
PubSubClient client(espClient);

//


//settings for internet and mqtt connection
const char* ssid = ""; // wifi SSID
const char* password =  ""; // wifi password 
const char* mqttServer = ""; // mqtt server ip  to be sent by smartespiot by mail 
const int mqttPort = ; // mqtt port   to be sent by smartespiot by mail 
const char* mqttUser = ""; // mqtt username  to be sent by smartespiot by mail 
const char* mqttPassword = ""; // mqtt pass to be sent by smartespiot by mail 

//****

String Topik; //Our variable that we will use for comparison by keeping the tags/topic information from mqtt 
String data_value; // our variable to hold the message information
char message_store[100]; // variable to save the incoming message as a character 
//***//
int wificounter = 0; // for counting the number of trying connections
//**//

void setup() {
  Serial.begin(115200); // start serial communication at 115200 speed
  WiFi.begin(ssid, password); // start the wifi connection process

  while (WiFi.status() != WL_CONNECTED) { //
    delay(5000); //wait 5000ms
    Serial.println("Connecting to wifi..."); // wait until the wifi process connects
    //// trying 10 times connection after reset to esp
    wificounter = wificounter + 1;
    if (wificounter == 10) {
      ESP.reset();
    }
    /////
  }


  Serial.println("Wifi connection ready :)"); // print the connection made information to the serial port

  client.setServer(mqttServer, mqttPort);//start connecting to the mqtt server from the specified port
/////*****
client.setCallback(callback);
////******
  while (!client.connected()) { //wait until we connect to mqtt
    Serial.println("Connecting to MQTT server...");

    if (client.connect("nodemcu1", mqttUser, mqttPassword )) {//login to mqtt server with username and password with smartespIOT name

      Serial.println("MQTT connection established :) ");

    } else {

      Serial.print("Unable to connect... ");// If the connection cannot be established, let's give a warning
      Serial.print(client.state());             // print the problem description
      // We can understand the problem according to the information returned from the clients state.
      //-4 : MQTT_CONNECTION_TIMEOUT - the server did not respond in the ongoing time
      //-3 : MQTT_CONNECTION_LOST - network connection lost
      //-2 : MQTT_CONNECT_FAILED - network connection failed
      //-1 : MQTT_DISCONNECTED - disconnected
      //0 : MQTT_CONNECTED - connection established
      //1 : MQTT_CONNECT_BAD_PROTOCOL - The server does not support the requested MQTT version
      //2 : MQTT_CONNECT_BAD_CLIENT_ID - The server did not accept your information
      //3 : MQTT_CONNECT_UNAVAILABLE - The server did not accept the connectionetmed
      //4 : MQTT_CONNECT_BAD_CREDENTIALS - username password not accepted
      //5 : MQTT_CONNECT_UNAUTHORIZED - you are not authorized to connect


      delay(2000);   // wait two seconds and try connecting again
      ////
      ESP.reset(); // unable to connect esp reset
      ///
    }
  }
  ////*****
  client.subscribe("nodemcu1/number");
  ////*****
}

////reconnect funtion //
void reconnect() {
WiFi.disconnect();
  delay(100);
  
WiFi.begin(ssid, password); // start the wifi connection process

while (WiFi.status() != WL_CONNECTED) { //
  delay(5000); //wait 5000ms
  Serial.println("Connecting to wifi..."); // wait until the wifi process connects
  //// trying 10 times connection after reset to esp
  wificounter = wificounter + 1;
  if (wificounter == 10) {
    ESP.reset();
  }
  /////
}


Serial.println("Wifi connection ready :)"); // print the connection made information to the serial port

client.setServer(mqttServer, mqttPort);//start connecting to the mqtt server from the specified port
/////*****
client.setCallback(callback);
////******
while (!client.connected()) { //wait until we connect to mqtt
  Serial.println("Connecting to MQTT server...");

  if (client.connect("SmartEspIOT", mqttUser, mqttPassword )) {//login to mqtt server with username and password with smartespIOT name

    Serial.println("MQTT connection established :) ");

  } else {

    Serial.print("Unable to connect... ");// If the connection cannot be established, let's give a warning
    Serial.print(client.state());             // print the problem description
    // We can understand the problem according to the information returned from the clients state.
    //-4 : MQTT_CONNECTION_TIMEOUT - the server did not respond in the ongoing time
    //-3 : MQTT_CONNECTION_LOST - network connection lost
    //-2 : MQTT_CONNECT_FAILED - network connection failed
    //-1 : MQTT_DISCONNECTED - disconnected
    //0 : MQTT_CONNECTED - connection established
    //1 : MQTT_CONNECT_BAD_PROTOCOL - The server does not support the requested MQTT version
    //2 : MQTT_CONNECT_BAD_CLIENT_ID - The server did not accept your information
    //3 : MQTT_CONNECT_UNAVAILABLE - The server did not accept the connectionetmed
    //4 : MQTT_CONNECT_BAD_CREDENTIALS - username password not accepted
    //5 : MQTT_CONNECT_UNAUTHORIZED - you are not authorized to connect


    delay(2000);   // wait two seconds and try connecting again
    ////
    ESP.reset(); // unable to connect esp reset
    ///
  }
}
 ////*****
  client.subscribe("nodemcu1/number");
  ////*****
}
////////////////////////////////////////
///****
void callback(char* topic, byte* payload, unsigned int length) { // Let's get the incoming topic-tag information and message 
 int i = 0;
 Serial.println("message received");
 Serial.println(topic); // Let's print the incoming topic-tag information to the serial port 
   Topik = String (topic); // write it to our variable to use the incoming topic information 
  Serial.print("incomming message:");
  for (i = 0; i < length; i++) {
 Serial.print((char)payload[i]); // write the incoming message to the serial port 
    message_store[i] = ((char)payload[i]); // store the incoming characters as characters in the message store 
  }
  message_store[i] = '\0'; // find the end of the message 

// Now let's find our data from the incoming message 

 if (Topik == "nodemcu1/number"){
  data_value = (message_store);
 }
 
}
/////*******


void loop() {

  client.loop(); // mrun the mqtt data processing function
  ///// test client connected and start reconnect ///
  if (!client.connected()) {
    reconnect();
  }
  /////
  unsigned long previousMillis;
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= 2000) {
    client.publish("nodemcu1/numberresend", String(data_value).c_str());// send our message in the topic with the device name
    Serial.println("message send");
   previousMillis = currentMillis; 
  }
    
  
}