Ubidots Community

[SOLVED] Var subscribe problem

Been working on this for days. Tried many examples to subscribe to change state on an output using a switch on the dash. Everything seems to work except the output doesn’t change. Hardware and wiring is good.
I am obviously missing something simple. Thank You for any ideas!
John

Attempting MQTT connection…connected
Subscribed to:
/v1.6/devices/esp8266/temperature/lv
publishing to TOPIC:
/v1.6/devices/esp8266
JSON dict: {“stuff”: [{“value”: 10.00}]}
publishing to TOPIC:
/v1.6/devices/esp8266
JSON dict: {“stuff”: [{“value”: 10.00}]}
publishing to TOPIC:
/v1.6/devices/esp8266
JSON dict: {“stuff”: [{“value”: 10.00}]}
Attempting MQTT connection…connected
Subscribed to:
/v1.6/devices/esp8266/temperature/lv
publishing to TOPIC:
/v1.6/devices/esp8266
JSON dict: {“stuff”: [{“value”: 10.00}]}
publishing to TOPIC:
/v1.6/devices/esp8266
JSON dict: {“stuff”: [{“value”: 10.00}]}

/****************************************
 * Include Libraries
 ****************************************/
#include "UbidotsESPMQTT.h"

/****************************************
 * Define Constants
 ****************************************/
#define TOKEN "xxxx" // Your Ubidots TOKEN
#define WIFINAME "x" // Your SSID
#define WIFIPASS "xxx" // Your Wifi Pass

Ubidots client(TOKEN);

/****************************************
 * Auxiliar Functions
 ****************************************/

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  if ((char)payload[0]=='1'){
    digitalWrite(16, HIGH);
  }
  else{
    digitalWrite(16, LOW);
  }
  Serial.println();
}

/****************************************
 * Main Functions
 ****************************************/

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  client.ubidotsSetBroker("industrial.api.ubidots.com");
  client.setDebug(true); // Pass a true or false bool value to activate debug messages
  client.wifiConnection(WIFINAME, WIFIPASS);
  client.begin(callback);
  pinMode(16, OUTPUT);
  client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable's Labels
  }

void loop() {
  // put your main code here, to run repeatedly:
  if(!client.connected()){
      client.reconnect();
      client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable's Labels
      }
  client.add("stuff", 10);
  client.ubidotsPublish("esp8266");  // was "source1" in example???????
  client.loop();
  delay (15000);
  }

Hello @ardyjohn

Are you sure that your “boolean” variable, that one in the picture changing from 1 to 0 and viceversa, is labelled as “temperature” ? I cannot see any reason why your code wouldn’t subscribe correctly to the variable, and printed in the callback function.

Also, keep in mind that your micro is sleeping for for 15s: delay(15000) so if you make a change in Ubidots and the micro is asleep at that moment, you won’t see the change until it wakes up. You should wrap up the publication process with millis() Arduino function in order to prevent that from happening. For example:

unsigned long startMillis;
const unsigned long period = 15000;  // the value is a number of milliseconds, ie 15 seconds

void setup() {
  startMillis = millis();  //initial start time
}

void loop() {
  if (abs(millis() - startMillis) >= period) { // test whether the period has elapsed
    /*PUT PUBLICATION LOGIC HERE TO AVOID SLEEPING THE MICRO*/
    startMillis = millis();  //IMPORTANT to save the start time of the current LED state.
  }
}

–David

Hi David,
I changed to millis but the problem turns out to be if there is more than a 15 sec wait time the subscribe doesn’t work. I’m not familiar with what this line is:
/PUT PUBLICATION LOGIC HERE TO AVOID SLEEPING THE MICRO/
This code is basically your sub & pub example. I don’t remember having this much of a problem on Ubidots for education.
Thank You
John

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

Auxiliar Functions
****************************************/
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
if ((char)payload[0]=='1'){
digitalWrite(16, HIGH);
}
else{
digitalWrite(16, LOW);
}
Serial.println();
}

unsigned long startMillis;
const unsigned long period = 16000;  

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

Main Functions
****************************************/
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);

client.ubidotsSetBroker("industrial.api.ubidots.com");
client.setDebug(true); // Pass a true or false bool value to activate debug messages
client.wifiConnection(WIFINAME, WIFIPASS);
client.begin(callback);
pinMode(16, OUTPUT);
client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable’s Labels

startMillis = millis();  //initial start time

}

void loop() {
// put your main code here, to run repeatedly:

if (abs(millis() - startMillis) >= period) { // test whether the period has elapsed
    /*PUT PUBLICATION LOGIC HERE TO AVOID SLEEPING THE MICRO*/
    startMillis = millis();  //IMPORTANT to save the start time of the current LED state

if(!client.connected()){
client.reconnect();
client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable’s Labels
}
client.add("stuff", 10);
client.ubidotsPublish("esp8266"); 
client.loop();

   }
}

You need to take the following out of the millis() if statement and leave it directly in the loop():

if (!client.connected()) {
  client.reconnect();
  client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable’s Labels
}

Also, are you sure that your 1 – 0 variable is labelled as “temperature” ? Can you send an screenshot of this variable that includes its identification: label, name and ID?

Hi David, I can’t believe I’m having so much trouble with something so simple. My apologies. I have a 10 sec millis but I see it’s updating at 23 secs.

Reivised code.

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

Auxiliar Functions
****************************************/
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
if ((char)payload[0]=='1'){
digitalWrite(16, HIGH);
}
else{
digitalWrite(16, LOW);
}
Serial.println();
}

unsigned long startMillis;
const unsigned long period = 10000;  

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

Main Functions
****************************************/
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);

client.ubidotsSetBroker("industrial.api.ubidots.com");
client.setDebug(true); // Pass a true or false bool value to activate debug messages
client.wifiConnection(WIFINAME, WIFIPASS);
client.begin(callback);
pinMode(16, OUTPUT);
client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable’s Labels

startMillis = millis();  //initial start time

}

void loop() {
// put your main code here, to run repeatedly:

if (abs(millis() - startMillis) >= period) { // test whether the period has elapsed
    /*PUT PUBLICATION LOGIC HERE TO AVOID SLEEPING THE MICRO*/
    startMillis = millis();  //IMPORTANT to save the start time of the current LED state

}
if(!client.connected()){
client.reconnect();
client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable’s Labels
client.add("stuff", 10);
client.ubidotsPublish("esp8266"); 
client.loop();

   }
}

this piece of code is wrong:

You are triggering the loop() method and subscribing and publishing to variables just If the device is not connected, which makes no sense.

You should refer to the basic subscription and publish example from the Ubidots library docs to be able to reference how to solve that sort of errors.

Do not forget to add the line below in your setup() function

client.ubidotsSetBroker("industrial.api.ubidots.com");

if you are an owner of an Stem or Industrial Ubidots account.

All the best

OK, lets start from ground zero,
This is your example, sub does not work. Results are exactly as my first post.
Thanks, John

/****************************************
 * Include Libraries
 ****************************************/
#include "UbidotsESPMQTT.h"

/****************************************
 * Define Constants
 ****************************************/
#define TOKEN "xxx" // Your Ubidots TOKEN
#define WIFINAME "xx" //Your SSID
#define WIFIPASS "xx" // Your Wifi Pass

Ubidots client(TOKEN);

/****************************************
 * Auxiliar Functions
 ****************************************/

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  if ((char)payload[0]=='1'){
    digitalWrite(16, HIGH);
  }
  else{
    digitalWrite(16, LOW);
  }
  Serial.println();
}

/****************************************
 * Main Functions
 ****************************************/

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  client.setDebug(true); // Pass a true or false bool value to activate debug messages
  client.wifiConnection(WIFINAME, WIFIPASS);
  client.begin(callback);
  pinMode(16, OUTPUT);
  client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable's Labels
  client.ubidotsSetBroker("industrial.api.ubidots.com");
  }

void loop() {
  // put your main code here, to run repeatedly:
  if(!client.connected()){
      client.reconnect();
      client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable's Labels
      }
  client.add("stuff", 10);
  client.ubidotsPublish("source1");
  client.loop();
  delay (5000);
  }

Can you share your username to check your account, please?

OpusII

Your device API Label is source1, not esp8266 as you are using in your code.

As the library docs specify, you must set both device and variable labels properly to subscribe to an Ubidots account variable to retrieve values from our broker.

All the best

The code I’m using is your example code. source1 & esp8266 as you pointed out… It would be usefull if the example was correct. Looking at my first post you will see I questioned that and changed it so both would be the same. Either way the sub function still doesn’t work. Thank You for your continued help.
Note changes:

Ubidots client(TOKEN);

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

  • Auxiliar Functions
    ****************************************/

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(“Message arrived [”);
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
if ((char)payload[0]==‘1’){
digitalWrite(16, HIGH);
}
else{
digitalWrite(16, LOW);
}
Serial.println();
}

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

  • Main Functions
    ****************************************/

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
client.setDebug(true); // Pass a true or false bool value to activate debug messages
client.wifiConnection(WIFINAME, WIFIPASS);
client.begin(callback);
pinMode(16, OUTPUT);
client.ubidotsSubscribe(“source1”,“temperature”); //Insert the dataSource and Variable’s Labels
client.ubidotsSetBroker(“industrial.api.ubidots.com”);
}

void loop() {
// put your main code here, to run repeatedly:
if(!client.connected()){
client.reconnect();
client.ubidotsSubscribe(“source1”,“temperature”); //Insert the dataSource and Variable’s Labels
}
client.add(“stuff”, 10);
client.ubidotsPublish(“source1”);
client.loop();
delay (10000);
}

Hi @ardyjohn

Please set the broker before subscribing in the setup() function and try again. Like this:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  client.setDebug(true); // Pass a true or false bool value to activate debug messages
  client.ubidotsSetBroker(“industrial.api.ubidots.com”);
  client.wifiConnection(WIFINAME, WIFIPASS);
  client.begin(callback);
  pinMode(16, OUTPUT);
  client.ubidotsSubscribe(“source1”,“temperature”); //Insert the dataSource and Variable’s Labels
}

Find below a code snippet (the same of the example shared previously) that is working with your account, I have commented the publish lines to avoid publishing data to your account. I am not sure what are you doing wrong, but the script may serve you as reference

/****************************************
 * Include Libraries
 ****************************************/
#include "UbidotsESPMQTT.h"

/****************************************
 * Define Constants
 ****************************************/
#define TOKEN "...." // Your Ubidots TOKEN
#define WIFINAME "...." //Your SSID
#define WIFIPASS "...." // Your Wifi Pass

Ubidots client(TOKEN);

/****************************************
 * Auxiliar Functions
 ****************************************/

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  if ((char)payload[0]=='1'){
    digitalWrite(16, HIGH);
  }
  else{
    digitalWrite(16, LOW);
  }
  Serial.println();
}

/****************************************
 * Main Functions
 ****************************************/

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  client.setDebug(true); // Pass a true or false bool value to activate debug messages
  client.ubidotsSetBroker("industrial.api.ubidots.com");
  client.wifiConnection(WIFINAME, WIFIPASS);
  client.begin(callback);
  pinMode(16, OUTPUT);
  client.ubidotsSubscribe("source1","temperature"); //Insert the dataSource and Variable's Labels
  }

void loop() {
  // put your main code here, to run repeatedly:
  if(!client.connected()){
      client.reconnect();
      client.ubidotsSubscribe("esp8266","temperature"); //Insert the dataSource and Variable's Labels
      }
  //client.add("stuff", 10);
  //client.ubidotsPublish("source1");
  client.loop();
  }

Thanks to your help it is almost right. I “think” I have the code correct, but the problem is if you use more than 15 sec in milis the subscribe fails. 15 or less it works everytime. Publish always works no matter how long a delay… Some sort of timeout? Any ideas? Thanks!
Latest code:

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

  • Include Libraries
    ****************************************/
    #include “UbidotsESPMQTT.h”

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

  • Define Constants
    ****************************************/
    #define TOKEN “xxx” // Your Ubidots TOKEN
    #define WIFINAME “x” //Your SSID
    #define WIFIPASS “xx” // Your Wifi Pass

Ubidots client(TOKEN);

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

  • Auxiliar Functions
    ****************************************/

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(“Message arrived [”);
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
if ((char)payload[0]==‘1’){
digitalWrite(16, HIGH);
}
else{
digitalWrite(16, LOW);
}
Serial.println();
}

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

  • Main Functions

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

unsigned long startMillis;
const unsigned long period = 15000; // the value is a number of milliseconds, ie 15 seconds

void setup() {
startMillis = millis(); //initial start time

Serial.begin(115200);
client.setDebug(true); // Pass a true or false bool value to activate debug messages
client.ubidotsSetBroker(“industrial.api.ubidots.com”);
client.wifiConnection(WIFINAME, WIFIPASS);
client.begin(callback);
pinMode(16, OUTPUT);
client.ubidotsSubscribe(“source1”,“temperature”); //Insert the dataSource and Variable’s Labels
}

void loop() {
if (abs(millis() - startMillis) >= period) { // test whether the period has elapsed
/PUT PUBLICATION LOGIC HERE TO AVOID SLEEPING THE MICRO/
startMillis = millis(); //IMPORTANT to save the start time of the current LED state.

// put your main code here, to run repeatedly:
if(!client.connected()){
client.reconnect();
client.ubidotsSubscribe(“source1”,“temperature”); //Insert the dataSource and Variable’s Labels
}

client.add(“stuff”, 10);
client.ubidotsPublish(“source1”);
client.loop();

}
}

@ardyjohn

As suggested before, you need to take client.loop() and reconnection logic out of the publication logic using millis(). Here it is

void loop() {
    // put your main code here, to run repeatedly

    if(!client.connected()){
        client.reconnect();
        client.ubidotsSubscribe(“source1”,“temperature”); //Insert the dataSource and Variable’s Labels
    }

    if (abs(millis() - startMillis) >= period) { // test whether the period has elapsed
        client.add(“stuff”, 10);
        client.ubidotsPublish(“source1”);
        startMillis = millis(); // IMPORTANT to save the start time of the current LED state.
    }

    client.loop();
}

Thank You!!! Got it working as expected. I finally understand what was needed.
Best Regards,
John