Ubidots Community

[SOLVED] Cannot Subscribe to variable when delay is above 5 seconds

Hello,
i created a project using esp32 and pubsubclient libraray using ubidots,
Iam publishing 5 variables and subscribing to 1 .
When i put a delay of 2000ms or 2seconds everything work fine.
But when i put a delay of 5000 ms or above i cannot subscribe to the variable (the variable is a switch whose data is used to turn on and off an led.)
values are publishing fine ,but cant subscribe to the topic.
the code is below …

#include <WiFi.h>
#include<PubSubClient.h>
#include <DHT.h>
#include <Wire.h>
#include <BH1750.h>  

BH1750 lightMeter; 
#define WIFISSID "xxxxxxxxx" 
#define PASSWORD "xxxxxxxx"
 
#define TOKEN "xxxxxxxxx" 
#define MQTT_CLIENT_NAME "xxxxxxxxx" 

#define VARIABLE_LABEL_SUBSCRIBE "switch_1"					
#define VARIABLE_LABEL_PIR "pir_sensor" 					
#define VARIABLE_LABEL_HUMIDITY "humi_dht11" 				
#define VARIABLE_LABEL_TEMPERATURE "temp_dht11" 		
#define VARIABLE_LABEL_SOIL "soil_moisture"					
#define VARIABLE_LABEL_LIGHT "light_intensity"				
#define DEVICE_LABEL "esp32" 								
#define LAMP_PIN 2
#define PIR_SENSOR_PIN 4 								
#define SOIL_SENSOR_PIN A0   								
#define DHTPIN 5
#define DHTTYPE DHT11


char mqttBroker[]  ="industrial.api.ubidots.com";
char payload[2000];
char topic[1000];


char*  topic1 = "/v1.6/devices/esp32/switch_1/lv";
char topicSubscribe[100];

char str_pir_sensor[10];
char str_soil_sensor[10];
char str_temp_sensor[10];
char str_hum_sensor[10];
char str_light_sensor[10];

WiFiClient ubidots;
PubSubClient client(ubidots);
DHT dht(DHTPIN, DHTTYPE);


void callback(char* topic1, byte* payload, unsigned int length) 
{
  
  Serial.print("Message arrived [");
  Serial.print(topic1);
  Serial.print("] ");

 
  
     for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  
    
    if ((char)payload[0]=='1'){
      digitalWrite(LAMP_PIN, HIGH);
    }
    else{
      digitalWrite(LAMP_PIN , LOW);
    }
  

}



void reconnect() 
{

	while (!client.connected()) 
	{
    	Serial.println("Attempting MQTT connection...");
    	if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) 
    	{
      		Serial.println("Connected");
    	} 
    	else 
    	{
      		Serial.print("Failed, rc=");
      		Serial.print(client.state());
      		Serial.println(" try again in 2 seconds");
      		delay(2000);
    	}
  }
}

void setup() 
{
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  Wire.begin(); 
  lightMeter.begin();
  dht.begin();
  pinMode(LAMP_PIN,OUTPUT); 
 
  
  Serial.println();
  Serial.print("Wait for WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) 
  {
    Serial.print(".");
    delay(500);
  }
  
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);  

 sprintf(topicSubscribe, "/v1.6/devices/%s/%s/lv", DEVICE_LABEL, VARIABLE_LABEL_SUBSCRIBE);
  
  client.subscribe(topicSubscribe);
}



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

   client.subscribe(topicSubscribe);

    
	
  }
 client.subscribe(topicSubscribe);

    
  static int count=0;
  count++ ;
  Serial.print("loop has executed");
  Serial.println(count);
  

   float pir_sensor_output = digitalRead(PIR_SENSOR_PIN); 
   float light_intensity_sensor_output = lightMeter.readLightLevel(); 
   float humidity = dht.readHumidity();
   float temperature = dht.readTemperature();  
   float soil_moisture_sensor_output = ( 100.00 - ( (analogRead(A0) / 4095.00) * 100.00 ) );
   
   dtostrf(pir_sensor_output, 1, 1, str_pir_sensor);  
   dtostrf(light_intensity_sensor_output, 4, 2, str_light_sensor);
   dtostrf(humidity, 4, 2, str_hum_sensor);
   dtostrf(temperature, 4, 2, str_temp_sensor);
   dtostrf(soil_moisture_sensor_output, 4, 2, str_soil_sensor);
   
 //////////////////////////////////////////////////////////////// 

   

   
  sprintf(topic, "%s", ""); 											
  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
  sprintf(payload, "%s", "");
  sprintf(payload, "{\"%s\":%s,", VARIABLE_LABEL_PIR, str_pir_sensor); 
  sprintf(payload, "%s \"%s\":%s,", payload, VARIABLE_LABEL_LIGHT, str_light_sensor);
  sprintf(payload, "%s \"%s\":%s}", payload, VARIABLE_LABEL_SOIL, str_soil_sensor);

  Serial.println("Publishing data to Ubidots Cloud");
  Serial.println(payload);
  client.publish(topic, payload);
  
  delay(2000);
  
   sprintf(topic, "%s", ""); 
   sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
   sprintf(payload, "%s", "");
   sprintf(payload, "{\"%s\":%s,", VARIABLE_LABEL_TEMPERATURE, str_temp_sensor); 
   sprintf(payload, "%s \"%s\":%s}", payload, VARIABLE_LABEL_HUMIDITY, str_hum_sensor); 
 
  
  Serial.println("Publishing data to Ubidots Cloud");
  Serial.println(payload);
  client.publish(topic, payload);
  
  delay(2000);
  

  client.loop();
  delay(2000);
}

Also tried changing callback and setup functions like below ,but its not working

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  Serial.write(payload, length);
  Serial.println(topic);

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  char value[20];
  
  
  for (int i = 0; i < 20; i++) {
    value[i] = '\0';
  }
  
  for (int i=0;i<length;i++) {
    char c = (char)payload[i];
    value[i] = payload[i];
    Serial.print(c);
  }
  Serial.println();

  float f_value = atof(value);
  if (f_value == 0) {
    digitalWrite(lamp_pin, LOW);
  } else {
    digitalWrite(lamp_pin, HIGH);
  }  
}



void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  Wire.begin(); 
  lightMeter.begin();
  
  //pinMode(SENSOR, INPUT);	
  pinMode(lamp_pin,OUTPUT); 
  dht.begin();
  
  Serial.println();
  Serial.print("Wait for WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);  

  sprintf(topicSubscribe, "/v1.6/devices/%s/%s/lv", DEVICE_LABEL, VARIABLE_LABEL_SUBSCRIBE);
  
  client.subscribe(topicSubscribe);
}

you should not add any delay to the loop() method, as this method is intended to maintain the socket connection. If you need to wait any amount of seconds before publishing data, use the millis() method instead of delay()

All the best

Hello @desd.batch2

This is the correct implementation of the millis() function to serve your purpose:

unsigned long timeStart;

void setup()
{
    timeStart = millis();

    // Your code here for the setup
}

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

    if (abs(millis() - timeStart) > 2000)
    {
        float pir_sensor_output = digitalRead(PIR_SENSOR_PIN);
        float light_intensity_sensor_output = lightMeter.readLightLevel();
        float humidity = dht.readHumidity();
        float temperature = dht.readTemperature();
        float soil_moisture_sensor_output = (100.00 - ((analogRead(A0) / 4095.00) * 100.00));

        dtostrf(pir_sensor_output, 1, 1, str_pir_sensor);
        dtostrf(light_intensity_sensor_output, 4, 2, str_light_sensor);
        dtostrf(humidity, 4, 2, str_hum_sensor);
        dtostrf(temperature, 4, 2, str_temp_sensor);
        dtostrf(soil_moisture_sensor_output, 4, 2, str_soil_sensor);

        ////////////////////////////////////////////////////////////////
        sprintf(topic, "%s", "");
        sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
        sprintf(payload, "%s", "");
        sprintf(payload, "{\"%s\":%s,", VARIABLE_LABEL_PIR, str_pir_sensor);
        sprintf(payload, "%s \"%s\":%s,", payload, VARIABLE_LABEL_LIGHT, str_light_sensor);
        sprintf(payload, "%s \"%s\":%s}", payload, VARIABLE_LABEL_SOIL, str_soil_sensor);

        Serial.println("Publishing data to Ubidots Cloud");
        Serial.println(payload);
        client.publish(topic, payload);

        delay(1000);

        sprintf(payload, "%s", "");
        sprintf(payload, "{\"%s\":%s,", VARIABLE_LABEL_TEMPERATURE, str_temp_sensor);
        sprintf(payload, "%s \"%s\":%s}", payload, VARIABLE_LABEL_HUMIDITY, str_hum_sensor);

        Serial.println("Publishing data to Ubidots Cloud");
        Serial.println(payload);
        client.publish(topic, payload);

        timeStart = millis();
    }

    client.loop();
}

All the best,

–David

Thanks …
This worked very well…

1 Like