Mqtt communication RPi and Wemos D1

Hi,

I am not that experience with Mqtt but i did manage to set up communication between my raspberry and a Wemos D1.

i have a raspberry pi 3b that communicates with a Wemos D1 by mqtt.
the communication works but is very slow.
also in my dashboard often it shows connection lost.
i there a way to speed up the communication?

Can you define 'slow'?
Is the Pi wireless of hardwired to the network?
What else is running on the network?
How ofter is the WeMos communicating and how much data is sent?
what do you mean when you say?

what version of NR and node.js (see startup log)?
What is running on the WeMos?

Also... what is the wifi signal strength of the WeMos?
Most wifi libraries that are used, normally produce a signal strength reading which you could send via MQTT to your Raspberry to check.

All,

thank you for your response.
from pressing the light button in the node red dashboard to switching on the light will take 4-6s.
the light is connected to the Wemos.
i am using my home wifi network, sow maybe i should create a local wifi network?
how often data is sent i am not sure, but you will find the arduino code on the bottom.
the node red version i use is v1.0.6
the Wemos is running by arduino


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

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
DHTesp dht;


// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "**********";
const char* password = "**********";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "192.168.192.65";

// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);

// DHT Sensor 
const int DHTPin = 12;

// S1 
const int s1 = 5;
int  switch1last = 0;
// S2 
const int s2 = 4;
int  switch2last = 0;
// S3 
const int s3 = 0;
int  switch3last = 0;

// Lamp1 
const int lamp1 = 16;
// Lamp2 
const int lamp2 = 14;
// Lamp3 
const int lamp3 = 13;

// Analog output pin dimmer1 
const int analogOutPinDimmer1 = 2; 
int outputValueDimmer1 = 0;        // value output to the PWM (analog out)
// relais Dimmer 1
const int rd1 = 15;


// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;

// Don't change the function below. This functions connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());
}

// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that 
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic room/lampx, you check if the message is either on or off. Turns the lampx GPIO according to the message
  if(topic=="room/lamp1"){
      Serial.print("Changing Room lamp1 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp1, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp1, LOW);
        Serial.print("Off");
      }
  }
        if(topic=="room/lamp2"){
      Serial.print("Changing Room lamp2 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp2, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp2, LOW);
        Serial.print("Off");
      }
  }

        if(topic=="room/lamp3"){
      Serial.print("Changing Room lamp3 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp3, HIGH);
        digitalWrite(rd1, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp3, LOW);
        digitalWrite(rd1, LOW);
        Serial.print("Off");
      }
  }

     if(topic=="room/dimmer1"){
    Serial.print ("Dimmer1 ");
    analogWrite(analogOutPinDimmer1, messageTemp.toInt());
      Serial.print(messageTemp);
      }
 }


// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    /*
     YOU MIGHT NEED TO CHANGE THIS LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
     To change the ESP device ID, you will have to give a new name to the ESP8266.
     Here's how it looks:
       if (client.connect("ESP8266Client")) {
     You can do it like this:
       if (client.connect("ESP1_Office")) {
     Then, for the other ESP:
       if (client.connect("ESP2_Garage")) {
      That should solve your MQTT multiple connections problem
    */
    if (client.connect("ESP8266Client1")) {
      Serial.println("connected");  
      // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more LEDs in this example)
      client.subscribe("room/lamp1");
      client.subscribe("room/lamp2");
      client.subscribe("room/lamp3");
      client.subscribe("room/dimmer1");
      
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
  pinMode(lamp1, OUTPUT);
  pinMode(lamp2, OUTPUT);
  pinMode(lamp3, OUTPUT);
  pinMode(rd1, OUTPUT);
  pinMode(s1, INPUT_PULLUP);
  pinMode(s2, INPUT_PULLUP);
  pinMode(s3, INPUT_PULLUP);
  
  Serial.begin(115200);
   dht.setup(D6, DHTesp::DHT22);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

}

// For this project, you don't need to change anything in the loop function. Basically it ensures that you ESP is connected to your broker
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("ESP8266Client");

  now = millis();
  // Publishes new temperature and humidity every 10 seconds
  if (now - lastMeasure > 10000) {
    lastMeasure = now;
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.getHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.getTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
   // float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
   // if (isnan(h) || isnan(t) || isnan(f)) {
  // if (isnan(h) || isnan(t)) {
   //   Serial.println("Failed to read from DHT sensor!");
    //  return;
   // }

    // Computes temperature values in Celsius
    float hic = dht.computeHeatIndex(t, h, false);
    static char temperatureTemp[7];
    dtostrf(hic, 6, 2, temperatureTemp);
    
    // Uncomment to compute temperature values in Fahrenheit 
    // float hif = dht.computeHeatIndex(f, h);
    // static char temperatureTemp[7];
    // dtostrf(hic, 6, 2, temperatureTemp);
    
    static char humidityTemp[7];
    dtostrf(h, 6, 2, humidityTemp);

    // Publishes Temperature and Humidity values
    //temperatureTemp = t;
    //humidityTemp = h;
    client.publish("room/temperature", temperatureTemp);
    client.publish("room/humidity", humidityTemp);
    
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
   // Serial.print(f);
   // Serial.print(" *F\t Heat index: ");
   // Serial.print(hic);
   // Serial.println(" *C ");
    // Serial.print(hif);
    // Serial.println(" *F");
  }

//switch 1
int  switch1 = digitalRead(s1);
int l1 = digitalRead(lamp1);
  // compare the buttonState to its previous state
//  Serial.println(switch1);
 // Serial.println(switch1last);
// Serial.println(l1);
  if (switch1 != switch1last) {
    // if the state has changed, increment the counter
    if (switch1 == 1 && l1 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch1on", "on");
    }  else  if (switch1 == 1 && l1 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch1off", "off");
    } 
  }
    if (switch1 != switch1last) {
    // if the state has changed, increment the counter
    if (switch1 == 0 && l1 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch1on", "on");
    }     else if (switch1 == 0 && l1 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch1off", "off");
    } 
  }

  //switch 2
int  switch2 = digitalRead(s2);
int l2 = digitalRead(lamp2);
  // compare the buttonState to its previous state
 // Serial.println(switch2);
 // Serial.println(switch1last);
// Serial.println(l2);
  if (switch2 != switch2last) {
    // if the state has changed, increment the counter
    if (switch2 == 1 && l2 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch2on", "on");
    }  else  if (switch2 == 1 && l2 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch2off", "off");
    } 
  }
    if (switch2 != switch2last) {
    // if the state has changed, increment the counter
    if (switch2 == 0 && l2 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch2on", "on");
    }     else if (switch2 == 0 && l2 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch2off", "off");
    } 
  }

    //switch 3
int  switch3 = digitalRead(s3);
int l3 = digitalRead(lamp3);
  // compare the buttonState to its previous state
 // Serial.println(switch2);
 // Serial.println(switch1last);
// Serial.println(l2);
  if (switch3 != switch3last) {
    // if the state has changed, increment the counter
    if (switch3 == 1 && l3 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch3on", "on");
    }  else  if (switch3 == 1 && l3 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch3off", "off");
    } 
  }
    if (switch3 != switch3last) {
    // if the state has changed, increment the counter
    if (switch3 == 0 && l3 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch3on", "on");
    }     else if (switch3 == 0 && l3 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch3off", "off");
    } 
  }
  // save the current state as the last state, for next time through the loop
 switch1last = switch1;
 switch2last = switch2;
 switch3last = switch3;
delay (1000);
}


 

In a "normal" situation the communication via MQTT (on a "normal" modern wifi home network) between an ESP device and another PC/RPi is very fast, instant, you should actually not be able to notice any delay at all.
I suggest you start to trace where the problem lies; is it in your wifi network? Try to establish a MQTT connection between two computers running NR and send MQTT messages between them. Do you see the same delays? Try to upload "another" fw to the ESP and check if it then shows. the same delay

I had a short look at your code.
The 'delay(1000);' statement at the very end of your loop section is bad for ESPs (but perfectly OK of Arduino devices).
With an ESP device, the loop() section needs to loop as often as possible, since this allows the ESP to handle the background tasks for the WiFi/TCP stack.
Just delete this line. Once we have this out of the way, we will see if your problem is still there.

1 Like

i tried to do this but it makes no difference.

Use println statements to work out where is the delay. With such a large delay that should not be difficult.

(your question finally prompted me to register as I think I can help you :slight_smile: )

I think the 5 second delay in your reconnect() is the problem, remove the following from the reconnect code:

  // Wait 5 seconds before retrying
  delay(5000);

You can leave the print statements in there to aid debug.

You need your re-connect to be 'non-blocking' by putting something like this in your loop() see the pubsub library examples for none blocking but this is what I have in all my ESP MQTT devices as an example:

//None Blocking MQTT reconnect every 15 seconds
if (millis() - lastReconnectAttempt > 15000)
{
// Attempt to reconnect
if (!mqttclient.connected())
{
if (reconnect())
{
lastReconnectAttempt = 0;
}
}
lastReconnectAttempt = millis();
}

i think this could be it.
sow i looked up the example and put it in my code, but it looks like i would not connect to the mqtt server anymore.
sow i put in your code, and the same thing.
maby you can have a look if i did something wrong?


/*****
 
 All the resources for this project:
 https://randomnerdtutorials.com/
 
*****/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
DHTesp dht;


// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "HZN246348759";
const char* password = "n8gKhVuggyre";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "192.168.192.65";

// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);

// DHT Sensor 
const int DHTPin = 12;

// S1 
const int s1 = 5;
int  switch1last = 0;
// S2 
const int s2 = 4;
int  switch2last = 0;
// S3 
const int s3 = 0;
int  switch3last = 0;

// Lamp1 
const int lamp1 = 16;
// Lamp2 
const int lamp2 = 14;
// Lamp3 
const int lamp3 = 13;

// Analog output pin dimmer1 
const int analogOutPinDimmer1 = 2; 
int outputValueDimmer1 = 0;        // value output to the PWM (analog out)
// relais Dimmer 1
const int rd1 = 15;


// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;

// Don't change the function below. This functions connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());
}

// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that 
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {
  
  Serial.print("Hier ben ik 1");
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT
Serial.print("Hier ben ik 2");
  // If a message is received on the topic room/lampx, you check if the message is either on or off. Turns the lampx GPIO according to the message
  if(topic=="room/lamp1"){
      Serial.print("Changing Room lamp1 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp1, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp1, LOW);
        Serial.print("Off");
      }
  }
        if(topic=="room/lamp2"){
      Serial.print("Changing Room lamp2 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp2, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp2, LOW);
        Serial.print("Off");
      }
  }

        if(topic=="room/lamp3"){
      Serial.print("Changing Room lamp3 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp3, HIGH);
        digitalWrite(rd1, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp3, LOW);
        digitalWrite(rd1, LOW);
        Serial.print("Off");
      }
  }

     if(topic=="room/dimmer1"){
    Serial.print ("Dimmer1 ");
    analogWrite(analogOutPinDimmer1, messageTemp.toInt());
      Serial.print(messageTemp);
      }
 }


long lastReconnectAttempt = 0;

boolean reconnect() {
  if (client.connect("ESP8266Client1")) {
    // Once connected, publish an announcement...
    client.publish("outTopic","hello world");
    // ... and resubscribe
    client.subscribe("inTopic");
  }
  return client.connected();
}


// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
  pinMode(lamp1, OUTPUT);
  pinMode(lamp2, OUTPUT);
  pinMode(lamp3, OUTPUT);
  pinMode(rd1, OUTPUT);
  pinMode(s1, INPUT_PULLUP);
  pinMode(s2, INPUT_PULLUP);
  pinMode(s3, INPUT_PULLUP);

  lastReconnectAttempt = 0;
  
  Serial.begin(115200);
   dht.setup(D6, DHTesp::DHT22);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

// For this project, you don't need to change anything in the loop function. Basically it ensures that you ESP is connected to your broker
void loop() {

//None Blocking MQTT reconnect every 15 seconds
//{
//  if (!client.connected()) {
//    long now = millis();
//    Serial.print("Client connect if 1 "); 
//    if (now - lastReconnectAttempt > 15000) { 
//     lastReconnectAttempt = now;
//    Serial.print("Client connect if 2 "); 
      // Attempt to reconnect
//      if (reconnect()) {
//        lastReconnectAttempt = 0;
//        Serial.print("Client connect if 3 "); 
//      }
//    }
//  } else {
    // Client connected
//   Serial.print("Client Connect else "); 
//    client.loop();
//  }

//}

//None Blocking MQTT reconnect every 15 seconds
//Serial.print(lastReconnectAttempt);
if (millis() - lastReconnectAttempt > 15000)
{
Serial.print("if 111111111111111");
// Attempt to reconnect
if (!client.connected())
{Serial.print("if 22222222222222222");
if (reconnect())
{Serial.print("if 333333333333333333");
lastReconnectAttempt = 0;
}
}
lastReconnectAttempt = millis();
}


  now = millis();
  // Publishes new temperature and humidity every 10 seconds
  if (now - lastMeasure > 15000) {
    lastMeasure = now;
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.getHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.getTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
   // float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
   // if (isnan(h) || isnan(t) || isnan(f)) {
  // if (isnan(h) || isnan(t)) {
   //   Serial.println("Failed to read from DHT sensor!");
    //  return;
   // }

    // Computes temperature values in Celsius
    float hic = dht.computeHeatIndex(t, h, false);
    static char temperatureTemp[7];
    dtostrf(hic, 6, 2, temperatureTemp);
    
    // Uncomment to compute temperature values in Fahrenheit 
    // float hif = dht.computeHeatIndex(f, h);
    // static char temperatureTemp[7];
    // dtostrf(hic, 6, 2, temperatureTemp);
    
    static char humidityTemp[7];
    dtostrf(h, 6, 2, humidityTemp);

    // Publishes Temperature and Humidity values
    //temperatureTemp = t;
    //humidityTemp = h;
    client.publish("room/temperature", temperatureTemp);
    client.publish("room/humidity", humidityTemp);
    
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
   // Serial.print(f);
   // Serial.print(" *F\t Heat index: ");
   // Serial.print(hic);
   // Serial.println(" *C ");
    // Serial.print(hif);
    // Serial.println(" *F");
  }

//switch 1
int  switch1 = digitalRead(s1);
int l1 = digitalRead(lamp1);
  // compare the buttonState to its previous state
//  Serial.println("switch1");
//  Serial.println(switch1);
// Serial.println(l1);
  if (switch1 != switch1last) {
    // if the state has changed, increment the counter
    if (switch1 == 1 && l1 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch1on", "on");
    }  else  if (switch1 == 1 && l1 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch1off", "off");
    } 
  }
    if (switch1 != switch1last) {
    // if the state has changed, increment the counter
    if (switch1 == 0 && l1 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch1on", "on");
    }     else if (switch1 == 0 && l1 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch1off", "off");
    } 
  }

  //switch 2
int  switch2 = digitalRead(s2);
int l2 = digitalRead(lamp2);
  // compare the buttonState to its previous state
//  Serial.println("switch2");
 // Serial.println(switch1last);
// Serial.println(l2);
  if (switch2 != switch2last) {
    // if the state has changed, increment the counter
    if (switch2 == 1 && l2 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch2on", "on");
    }  else  if (switch2 == 1 && l2 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch2off", "off");
    } 
  }
    if (switch2 != switch2last) {
    // if the state has changed, increment the counter
    if (switch2 == 0 && l2 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch2on", "on");
    }     else if (switch2 == 0 && l2 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch2off", "off");
    } 
  }

    //switch 3
int  switch3 = digitalRead(s3);
int l3 = digitalRead(lamp3);
  // compare the buttonState to its previous state
//  Serial.println("switch3");
 // Serial.println(switch3last);
// Serial.println(l3);
  if (switch3 != switch3last) {
    // if the state has changed, increment the counter
    if (switch3 == 1 && l3 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch3on", "on");
    }  else  if (switch3 == 1 && l3 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch3off", "off");
    } 
  }
    if (switch3 != switch3last) {
    // if the state has changed, increment the counter
    if (switch3 == 0 && l3 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch3on", "on");
    }     else if (switch3 == 0 && l3 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch3off", "off");
    } 
  }
  // save the current state as the last state, for next time through the loop
 switch1last = switch1;
 switch2last = switch2;
 switch3last = switch3;
// delay (1000);
}


 

You need to connect to the MQTT server in order to use it, your code at the moment will try to connect to a MQTT server called "ESP8266Client1" but I could not see this defined anywhere, you probably meant 'mqtt_server' ?

Additionally I would add a reconnect(); in to the setup() before the last '}' else you will have to wait until the first run through the reconnect() in the loop before you get any MQTT messages.

Hope that helps :slight_smile:

Sow i managed to make it work by the mqtt_reconnect_nonblocking example.
but still about 4 seconds delay.
sow if i push the button on my Nope Red dashboard, the message would arrive in this line
void callback(String topic, byte* message, unsigned int length)
after this i do a serial print.
after pressing the button it also takes about 3-4 seconds before i will get the serial print.
Could it be that the delay is in my wifi network? or has this nothing to do with it?


/*****
 
 All the resources for this project:
 https://randomnerdtutorials.com/
 
*****/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
DHTesp dht;


// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "***************";
const char* password = "*****************";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "192.168.192.65";


// DHT Sensor 
const int DHTPin = 12;

// S1 
const int s1 = 5;
int  switch1last = 0;
// S2 
const int s2 = 4;
int  switch2last = 0;
// S3 
const int s3 = 0;
int  switch3last = 0;

// Lamp1 
const int lamp1 = 16;
// Lamp2 
const int lamp2 = 14;
// Lamp3 
const int lamp3 = 13;

// Analog output pin dimmer1 
const int analogOutPinDimmer1 = 2; 
int outputValueDimmer1 = 0;        // value output to the PWM (analog out)
// relais Dimmer 1
const int rd1 = 15;

  // Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient1;
PubSubClient client(espClient1);

// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;

// Don't change the function below. This functions connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());
}

// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that 
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {

  // Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
//WiFiClient espClient1;
//PubSubClient client(espClient1);
  
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT
  // If a message is received on the topic room/lampx, you check if the message is either on or off. Turns the lampx GPIO according to the message
  if(topic=="room/lamp1"){
      Serial.print("Changing Room lamp1 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp1, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp1, LOW);
        Serial.print("Off");
      }
  }
        if(topic=="room/lamp2"){
      Serial.print("Changing Room lamp2 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp2, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp2, LOW);
        Serial.print("Off");
      }
  }

        if(topic=="room/lamp3"){
      Serial.print("Changing Room lamp3 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp3, HIGH);
        digitalWrite(rd1, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp3, LOW);
        digitalWrite(rd1, LOW);
        Serial.print("Off");
      }
  }

     if(topic=="room/dimmer1"){
    Serial.print ("Dimmer1 ");
    analogWrite(analogOutPinDimmer1, messageTemp.toInt());
      Serial.print(messageTemp);
      }
 }


// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266 
long lastReconnectAttempt = 0;

boolean reconnect() {
  if (client.connect("ESP8266Client1")) {
    // Once connected, publish an announcement...
    Serial.print("Mqtt Connected begin loop");
       // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more LEDs in this example)
      client.subscribe("room/lamp1");
      client.subscribe("room/lamp2");
      client.subscribe("room/lamp3");
      client.subscribe("room/dimmer1");
    Serial.print("Mqtt Connected end loop");
  }
  return client.connected();
}

// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
  pinMode(lamp1, OUTPUT);
  pinMode(lamp2, OUTPUT);
  pinMode(lamp3, OUTPUT);
  pinMode(rd1, OUTPUT);
  pinMode(s1, INPUT_PULLUP);
  pinMode(s2, INPUT_PULLUP);
  pinMode(s3, INPUT_PULLUP);
  
  Serial.begin(115200);
   dht.setup(D6, DHTesp::DHT22);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  lastReconnectAttempt = 0;
}

// For this project, you don't need to change anything in the loop function. Basically it ensures that you ESP is connected to your broker
void loop() {

  {
  if (!client.connected()) {
    long now = millis();
    if (now - lastReconnectAttempt > 30000) {
      lastReconnectAttempt = now;
      // Attempt to reconnect
      if (reconnect()) {
        lastReconnectAttempt = 0;
      }
    }
  } else {
    // Client connected

    client.loop();
  }

}

  now = millis();
  // Publishes new temperature and humidity every 10 seconds
  if (now - lastMeasure > 10000) {
    lastMeasure = now;
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.getHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.getTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
   // float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
   // if (isnan(h) || isnan(t) || isnan(f)) {
  // if (isnan(h) || isnan(t)) {
   //   Serial.println("Failed to read from DHT sensor!");
    //  return;
   // }

    // Computes temperature values in Celsius
    float hic = dht.computeHeatIndex(t, h, false);
    static char temperatureTemp[7];
    dtostrf(hic, 6, 2, temperatureTemp);
    
    // Uncomment to compute temperature values in Fahrenheit 
    // float hif = dht.computeHeatIndex(f, h);
    // static char temperatureTemp[7];
    // dtostrf(hic, 6, 2, temperatureTemp);
    
    static char humidityTemp[7];
    dtostrf(h, 6, 2, humidityTemp);

    // Publishes Temperature and Humidity values
    //temperatureTemp = t;
    //humidityTemp = h;
    client.publish("room/temperature", temperatureTemp);
    client.publish("room/humidity", humidityTemp);
    
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
   // Serial.print(f);
   // Serial.print(" *F\t Heat index: ");
   // Serial.print(hic);
   // Serial.println(" *C ");
    // Serial.print(hif);
    // Serial.println(" *F");
  }

//switch 1
int  switch1 = digitalRead(s1);
int l1 = digitalRead(lamp1);
  // compare the buttonState to its previous state
//  Serial.println(switch1);
 // Serial.println(switch1last);
// Serial.println(l1);
  if (switch1 != switch1last) {
    // if the state has changed, increment the counter
    if (switch1 == 1 && l1 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch1on", "on");
    }  else  if (switch1 == 1 && l1 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch1off", "off");
    } 
  }
    if (switch1 != switch1last) {
    // if the state has changed, increment the counter
    if (switch1 == 0 && l1 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch1on", "on");
    }     else if (switch1 == 0 && l1 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch1off", "off");
    } 
  }

  //switch 2
int  switch2 = digitalRead(s2);
int l2 = digitalRead(lamp2);
  // compare the buttonState to its previous state
 // Serial.println(switch2);
 // Serial.println(switch1last);
// Serial.println(l2);
  if (switch2 != switch2last) {
    // if the state has changed, increment the counter
    if (switch2 == 1 && l2 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch2on", "on");
    }  else  if (switch2 == 1 && l2 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch2off", "off");
    } 
  }
    if (switch2 != switch2last) {
    // if the state has changed, increment the counter
    if (switch2 == 0 && l2 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch2on", "on");
    }     else if (switch2 == 0 && l2 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch2off", "off");
    } 
  }

    //switch 3
int  switch3 = digitalRead(s3);
int l3 = digitalRead(lamp3);
  // compare the buttonState to its previous state
 // Serial.println(switch2);
 // Serial.println(switch1last);
// Serial.println(l2);
  if (switch3 != switch3last) {
    // if the state has changed, increment the counter
    if (switch3 == 1 && l3 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch3on", "on");
    }  else  if (switch3 == 1 && l3 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch3off", "off");
    } 
  }
    if (switch3 != switch3last) {
    // if the state has changed, increment the counter
    if (switch3 == 0 && l3 == 0) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("on");
      client.publish("room/switch3on", "on");
    }     else if (switch3 == 0 && l3 == 1) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("off");
      client.publish("room/switch3off", "off");
    } 
  }
  // save the current state as the last state, for next time through the loop
 switch1last = switch1;
 switch2last = switch2;
 switch3last = switch3;
//delay (1000);
}


 

I'm not sure you can test for not connected before running the mqtt loop?

Try moving client.loop to after the "loop() {"

thank you for your respond, i will check this somewhere next week :wink:

still the same delay.
i will go try to set up the communication by serial.

Have you determined exactly where the delay is, as I suggested earlier? It should be easy with such a large delay. First check it is not in the flow before it gets to the MQTT publish, use a debug node for that.
If that is ok then add an MQTT In node in the node red flow subscribed to the topic and check that that fires as soon as you click your button.
If that is ok then include logging in the device that logs when the message is received. That will tell you if it is in the MQTT code in the device that the problem lies. It is certainly not normal to have such delays so there must be something wrong somewhere.

Also you said at the beginning that you regularly get connection lost displayed in node red. Is that the mqtt node showing that or the dashboard?

Have you got anything to see the MQTT traffic so you can confirm what is being sent and when it is being sent? Might help isolate where your delay is...

Suggest you try something like http://mqtt-explorer.com/

Cheers

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.