Publish and Subscribe in the same sketch

Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Locked
User avatar
pentiger
 
Posts: 17
Joined: Wed Jun 26, 2013 9:55 pm

Publish and Subscribe in the same sketch

Post by pentiger »

Hello, I successfully tested the digital_out example from the examples folder but there is a small problem.
I can light the lamp from the dashboard as well as from IFTTT, however if for example the lamp is already on when the ESP8266 connects to Adafruit.io the dashboard will not reflect the switch as turned on and there is a mismatch.
The obvious choice would be to read and publish the current state of the lamp to the IO before subscribing to the feed but frm what I have tried I cannot subscribe and publish the same feed in same sketch.

Is there a way to do it?
thanks.

User avatar
fapuc2
 
Posts: 13
Joined: Fri Oct 16, 2015 8:29 am

Re: Publish and Subscribe in the same sketch

Post by fapuc2 »

Hello, I think to set correspondence just impose
status off = 0 and the status on = 1 or not, when you create the feed.
I am also interested in this example as shown in the previous post.
I wonder how to set your script?

Thank you
Fabio

User avatar
pentiger
 
Posts: 17
Joined: Wed Jun 26, 2013 9:55 pm

Re: Publish and Subscribe in the same sketch

Post by pentiger »

The below example subscribes to two feeds "LAMP" and "LED1" both can be controlled independently.

sometimes however when I use Do button from IFTTT, Adfruit.IO will see the change and turn of the swith but the LED will stay lit, so it's not 100% bulletproof.

Code: Select all

/***************************************************
  Adafruit MQTT Library ESP8266 Example

  Must use ESP8266 Arduino from:
    https://github.com/esp8266/Arduino

  Works great with Adafruit's Huzzah ESP board:
  ----> https://www.adafruit.com/product/2471
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Tony DiCola for Adafruit Industries.
  Adafruit IO example additions by Todd Treece.
  MIT license, all text above must be included in any redistribution
 ****************************************************/
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/****************************** Pins ******************************************/

#define LAMP            2  // power switch tail
#define LED1            5  // power switch tail
/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "...................."
#define WLAN_PASS       "........................"

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "............................"
#define AIO_KEY         "........................"

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Store the MQTT server, client ID, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM    = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ AIO_USERNAME;
const char MQTT_USERNAME[] PROGMEM  = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM  = AIO_KEY;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);

/****************************** Feeds ***************************************/

// Setup a feed called 'lamp' for subscribing to changes.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
const char LAMP_FEED[] PROGMEM = AIO_USERNAME "/feeds/lamp";
Adafruit_MQTT_Subscribe lamp = Adafruit_MQTT_Subscribe(&mqtt, LAMP_FEED);
const char LED1_FEED[] PROGMEM = AIO_USERNAME "/feeds/led1";
Adafruit_MQTT_Subscribe led1 = Adafruit_MQTT_Subscribe(&mqtt, LED1_FEED);
/*************************** Sketch Code ************************************/

void setup() {

  // set power switch tail pin as an output
  pinMode(LAMP, OUTPUT);
  pinMode(LED1, OUTPUT);
  Serial.begin(115200);

  Serial.println(F("Adafruit IO Example"));

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  delay(10);
  Serial.print(F("Connecting to "));
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println();

  Serial.println(F("WiFi connected"));
  Serial.println(F("IP address: "));
  Serial.println(WiFi.localIP());

  // listen for events on the lamp feed
  mqtt.subscribe(&lamp);
  mqtt.subscribe(&led1);
  // connect to adafruit io
  connect();
  digitalWrite(LAMP,LOW);
  digitalWrite(LED1,LOW);
}

void loop() {

  Adafruit_MQTT_Subscribe *subscription;

  // ping adafruit io a few times to make sure we remain connected
  if(! mqtt.ping(3)) {
    // reconnect to adafruit io
    if(! mqtt.connected())
      connect();
  }

  // this is our 'wait for incoming subscription packets' busy subloop
  while (subscription = mqtt.readSubscription(1000)) {

    // we only care about the lamp events
  
  if (subscription == &lamp) {
      // convert mqtt ascii payload to int
      char *value = (char *)lamp.lastread;
      Serial.print(F("Received: "));
      Serial.println(value);
      int current = atoi(value);

      // write the current state to the power switch tail
      digitalWrite(LAMP, current == 1 ? HIGH : LOW);

  }
     if (subscription == &led1) {
      // convert mqtt ascii payload to int
      char *value = (char *)led1.lastread;
      Serial.print(F("Received: "));
      Serial.println(value);
      int current = atoi(value);

      // write the current state to the power switch tail
      digitalWrite(LED1, current == 1 ? HIGH : LOW);

  } 

  }

}

// connect to adafruit io via MQTT
void connect() {

  Serial.print(F("Connecting to Adafruit IO... "));

  int8_t ret;

  while ((ret = mqtt.connect()) != 0) {

    switch (ret) {
      case 1: Serial.println(F("Wrong protocol")); break;
      case 2: Serial.println(F("ID rejected")); break;
      case 3: Serial.println(F("Server unavail")); break;
      case 4: Serial.println(F("Bad user/pass")); break;
      case 5: Serial.println(F("Not authed")); break;
      case 6: Serial.println(F("Failed to subscribe")); break;
      default: Serial.println(F("Connection failed")); break;
    }

    if(ret >= 0)
      mqtt.disconnect();

    Serial.println(F("Retrying connection..."));
    delay(5000);

  }

  Serial.println(F("Adafruit IO Connected!"));

}

User avatar
fapuc2
 
Posts: 13
Joined: Fri Oct 16, 2015 8:29 am

Re: Publish and Subscribe in the same sketch

Post by fapuc2 »

sorry but your code I always returns:
-------------------------------
Adafruit IO Example
Connecting to xxxxx
WiFi connected
IP address:
yy.yy.yy.yy
Connecting to Adafruit IO... Failed to subscribe
Retrying connection...
Failed to subscribe
Retrying connection..
-----------------------

are you sure you can do two subscriptions with this code, because with a single subscription works fine
However, it was useful to understand my mistake.

thank you
Fabio

User avatar
pentiger
 
Posts: 17
Joined: Wed Jun 26, 2013 9:55 pm

Re: Publish and Subscribe in the same sketch

Post by pentiger »

I definitely works, it does connect longer, needs couple tries but it connects and subscribes to 2 feeds. https://www.youtube.com/watch?v=XsOaZXYGId8

k00kykelly
 
Posts: 7
Joined: Thu Feb 06, 2014 10:01 pm

Re: Publish and Subscribe in the same sketch

Post by k00kykelly »

If the names start out the same, you can also use the # wildcards to subscribe to multiples in one go.
http://www.hivemq.com/blog/mqtt-essenti ... -practices

User avatar
fapuc2
 
Posts: 13
Joined: Fri Oct 16, 2015 8:29 am

Re: Publish and Subscribe in the same sketch

Post by fapuc2 »

ok the code you posted was useful to identify my mistakes.
I modified your code for two feeds contemporary "LAMP" and "BUTTON"
with one public and one that subscribes.
Unfortunately I also confirm the incomplete stability 100%.
I modified delay times and also changed version Library "adafruit MTTT"
but the results are not always 100% stable.
The construction of dashboards "IO-Adafruit" is imy opinion very nice and intuitive
that should perhaps also developed schecth
the quality of service to guarantee actual sending or receiving event.

Regards

k00kykelly
 
Posts: 7
Joined: Thu Feb 06, 2014 10:01 pm

Re: Publish and Subscribe in the same sketch

Post by k00kykelly »

There is a stability thread going
viewtopic.php?f=56&t=83652

User avatar
fapuc2
 
Posts: 13
Joined: Fri Oct 16, 2015 8:29 am

Re: Publish and Subscribe in the same sketch

Post by fapuc2 »

Finally, this code seems to work well in both publishing and subscribing

Code: Select all

/***************************************************
  Adafruit MQTT Library ESP8266 Example

  Must use ESP8266 Arduino from:
    https://github.com/esp8266/Arduino

  Works great with Adafruit's Huzzah ESP board:
  ----> https://www.adafruit.com/product/2471
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Tony DiCola for Adafruit Industries.
  Adafruit IO example additions by Todd Treece.
  MIT license, all text above must be included in any redistribution



 ****************************************************/
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/****************************** Pins ******************************************/

  #define LAMP            2  // Led o BANNED Relè
  #define BUTTON          0  // switch fine corsa  normalmente aperto            //****************
/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "............"
#define WLAN_PASS       "......................."

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "........."
#define AIO_KEY         "................................."

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Store the MQTT server, client ID, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM    = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ AIO_USERNAME;
const char MQTT_USERNAME[] PROGMEM  = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM  = AIO_KEY;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);

/****************************** Feeds ***************************************/

// Setup a feed called 'lamp' for subscribing to changes.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname> //*****************************************************
const char LAMP_FEED[] PROGMEM = AIO_USERNAME "/feeds/lamp";                  //***
Adafruit_MQTT_Subscribe lamp = Adafruit_MQTT_Subscribe(&mqtt, LAMP_FEED);     //*** Subscribe (Riceve BANNED x relè motore )
const char BUTTON_FEED[] PROGMEM = AIO_USERNAME "/feeds/button";              //***
Adafruit_MQTT_Publish button = Adafruit_MQTT_Publish(&mqtt, BUTTON_FEED);     //*** Publish   (Trasmette lo stato del fine corsa)
//*******************************************************************************************************************************

/*************************** Sketch Code ************************************/

// button state
int current = 0;
int currentB = 0;
int last = -1;
int lastB = -1;



void setup() {

  // set pin ingresso uscita  ESP8266
  pinMode(LAMP, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);  //**************** "INPU_PULLUP" se ardware manca resistenza fisica di pullup verso +vcc
  Serial.begin(115200);

  Serial.println(F("Adafruit IO Example"));

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  delay(10);
  Serial.print(F("Connecting to "));
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }          
  Serial.println();

  Serial.println(F("WiFi connected"));
  Serial.println(F("IP address: "));
  Serial.println(WiFi.localIP());

  // listen for events on the lamp feed
  mqtt.subscribe(&lamp);
 // mqtt.subscribe(&button);     //**************** button è solo pubblicato
 // connect to adafruit io
  connect();
  digitalWrite(LAMP,LOW);    // stato iniziale al boot
  digitalWrite(BUTTON,LOW);  // stato iniziale al boot    ***************
}

void loop() {

  Adafruit_MQTT_Subscribe *subscription;

			// ping adafruit io a few times to make sure we remain connected
			if(! mqtt.ping(3)) {
			// reconnect to adafruit io
			if(! mqtt.connected())
			connect();
			}

// feeds/button ****************************************************************************************************************

       // grab the current state of the button
       current = digitalRead(BUTTON);
       // return if the value hasn't changed    // return se ilvalore non cambia     //**************************
       // if(current == last)                  // abilita questa riga e quella sopra e sotto
       // return;                             // per aspettare il cambio di stato prima di fare nuovo invio
                                             // invece se queste righe commentate questo feeds invia ciclicamente il suo stato 
											 
       int32_t value = (current == LOW ? 1 : 0);

       // Now we can publish stuff!
       Serial.print(F("\nSending button value: "));
       Serial.print(value);
       Serial.print("... ");
   if (! button.publish(value))
      Serial.println(F("Failed."));
			else
			Serial.println(F("Success!"));
			delay(5000);                       // *************************************
                                               // 5 secondi // intervallo x ogni invio
              // save the button state                                                   
              last = current;
      



  
// feeds/lamp ****************************************************************************************************************

    // this is our 'wait for incoming subscription packets' busy subloop
    while (subscription = mqtt.readSubscription(1000)) {

        // we only care about the lamp events
        if (subscription == &lamp) {
        // convert mqtt ascii payload to int
        char *value = (char *)lamp.lastread;
        Serial.print(F("Received: "));
        Serial.println(value);
        int current = atoi(value);

        // write the current state to the power switch tail
        digitalWrite(LAMP, current == 1 ? HIGH : LOW);

       }  
      
    }                                    

  }



// connect to adafruit io via MQTT
void connect() {

  Serial.print(F("Connecting to Adafruit IO... "));

  int8_t ret;

  while ((ret = mqtt.connect()) != 0) {

    switch (ret) {
      case 1: Serial.println(F("Wrong protocol")); break;
      case 2: Serial.println(F("ID rejected")); break;
      case 3: Serial.println(F("Server unavail")); break;
      case 4: Serial.println(F("Bad user/pass")); break;
      case 5: Serial.println(F("Not authed")); break;
      case 6: Serial.println(F("Failed to subscribe")); break;
      default: Serial.println(F("Connection failed")); break;
    }

    if(ret >= 0)
      mqtt.disconnect();

    Serial.println(F("Retrying connection..."));
    delay(5000);

  }

  Serial.println(F("Adafruit IO Connected!"));

}

Locked
Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.

Return to “Internet of Things: Adafruit IO and Wippersnapper”