0

Regarding Publish Subscribe
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Regarding Publish Subscribe

by yadnik17 on Thu Jul 04, 2019 7:46 am

Hello sir,
I am doing a project where I am sending a value of temperature sensor on your server and it's displaying that value on the server i.e on the gauge I can see sensor value, it means my publishing stuff working fine.
But when I am subscribing to a topic "onoff" feed the server gets closed and I again need to connect to the server to publish a sensor value.
What I am doing wrong?
I also watch Lady Ada mams video on youtube, where she perfectly doing this stuff using Arduino.
For this project I am using 8051 controller to send data and publishing stuff is working perfect but when I send a command from the server, the server gets close.
Is publishing data and subscribe to a topic work simultaneously? If yes then how to do that.
Please, sir, give any idea about it or suggest any method.
Your any help is appreciable.
Thank you.

yadnik17
 
Posts: 9
Joined: Sat Jun 08, 2019 10:46 am

Re: Regarding Publish Subscribe

by brubell on Fri Jul 05, 2019 9:40 am

But when I am subscribing to a topic "onoff" feed the server gets closed and I again need to connect to the server to publish a sensor value.


It sounds like you are using MQTT to publish/subscribe with the 8051. If publishing is working, there's a chance that the subscribe packet you're sending is malformed (which would cause the IO MQTT broker to close the connection with your client).

Check out the low-level MQTT specification's documentation about SUBSCRIBE for more information about this:
http://docs.oasis-open.org/mqtt/mqtt/v3 ... c398718063

brubell
 
Posts: 469
Joined: Fri Jul 17, 2015 10:33 pm

Re: Regarding Publish Subscribe

by yadnik17 on Wed Jul 10, 2019 9:03 am

Hello sir,
Is there any function available in Adafruit MQTT library to send string value to a server? I am using MQTT_fona example to send value to the server, but it allows me to send only integer value. When I am passing a string to publish function it gives an error and in error message, it shows that there is no such function in Adafruit MQTT library which take a string as a parameter.
Do suggest some code example.
Your any help is appreciable.
Thank you.

Thanks and Regards
yadnik

yadnik17
 
Posts: 9
Joined: Sat Jun 08, 2019 10:46 am

Re: Regarding Publish Subscribe

by brubell on Wed Jul 10, 2019 10:45 am

yadnik17 wrote:Hello sir,
Is there any function available in Adafruit MQTT library to send string value to a server? I am using MQTT_fona example to send value to the server, but it allows me to send only integer value. When I am passing a string to publish function it gives an error and in error message, it shows that there is no such function in Adafruit MQTT library which take a string as a parameter.
Do suggest some code example.
Your any help is appreciable.
Thank you.

Thanks and Regards
yadnik


You can pass a character array to publish:
Code: Select all | TOGGLE FULL SIZE
bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) {

via https://github.com/adafruit/Adafruit_MQ ... T.cpp#L300

So if you declare:
char mystring[101] = "Hello IO";

You would call:
client.publish(topic, mystring);

brubell
 
Posts: 469
Joined: Fri Jul 17, 2015 10:33 pm

Re: Regarding Publish Subscribe

by yadnik17 on Wed Jul 10, 2019 4:26 pm

Hello sir,
Thank you for your reply.
Actually, I subscribed to 'onoff' feed to toggle led which is connected to my Arduino and I have created Stream window and name it as "console" on adafruit io to see all messages publish from Arduino.

This is a code which is I am using.

Code: Select all | TOGGLE FULL SIZE
char mystring[50]  =  "Door is open"; // This is char Array which holds a string

void loop()
{
  // Make sure to reset watchdog every loop iteration!
     Watchdog.reset();

  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
     MQTT_connect();

     Watchdog.reset();

  // this is our 'wait for incoming subscription packets' busy subloop.......................................
     Adafruit_MQTT_Subscribe *subscription;
     while ((subscription = mqtt.readSubscription(5000)))
     {
         if (subscription == &onoffbutton)
         {
              Serial.print(F("Got: "));
              Serial.println((char *)onoffbutton.lastread);
             
              if (strcmp((char *)onoffbutton.lastread, "ON") == 0)   
               {   
                   digitalWrite(led, HIGH); delay(1000);   
               }
              else if (strcmp((char *)onoffbutton.lastread, "OFF") == 0)
               {   
                   digitalWrite(led, LOW);  delay(1000);   
               }
              else { 
                          /* come here and don't do anything....*/
                      }
         }
   
     }
     
  // Now we can publish stuff!................................................................................

     console.publish( "console", mystring);  // "console" is name given to Stream window on Adafruit io and used as Topic for publish.
     delay(500);
 }


I replaced both codes which are given below but not able to see any message on Stream window and subscription part also not working.

Code: Select all | TOGGLE FULL SIZE
console.publish( "console", mystring);
 delay(500);                                       

 console.publish( AIO_USERNAME "/feeds/console", mystring);  // my AIO_USERNAME is yadnik17
 delay(500); 

The main thing is both codes are compiling perfectly but after some time connection is close by the server.
As soon as server closes the connection, the controller again start code from the beginning like fonna is ok or not, GPRS is enabled or disabled, etc.

The mqtt_fona example is working for my fonna perfectly as it only sends integer value(counter value) and when any subscription appears it toggle led, depending on ON or OFF condition.

I am doing this stuff of sending 'string ' instead of the counter value, from last five days but not able to complete. I copied this code from mqttt_fona example from your library and made some changes but facing some problems which I have mentioned above.
please, sir, I really need your help, it means a lot for me. Your any help is appreciable.
Thank you.
Last edited by brubell on Wed Jul 10, 2019 6:10 pm, edited 1 time in total.
Reason: add code tags

yadnik17
 
Posts: 9
Joined: Sat Jun 08, 2019 10:46 am

Re: Regarding Publish Subscribe

by brubell on Wed Jul 10, 2019 6:16 pm

Ok - before we address the character issue, let's first try ensuring that you can stay connected to the server long enough to send data.

You can do this by calling the ping function to ping the network and server.

At the bottom of your loop(), add the following code:
Code: Select all | TOGGLE FULL SIZE
  // ping the server to keep the mqtt connection alive, only needed if we're not publishing
  if(! mqtt.ping()) {
    Serial.println(F("MQTT Ping failed."));
  }


Let me know if you stay connected to the server and we'll continue to sending strings.

brubell
 
Posts: 469
Joined: Fri Jul 17, 2015 10:33 pm

Re: Regarding Publish Subscribe

by yadnik17 on Thu Jul 11, 2019 5:48 am

Hello sir,
After pinging the server, still showing the same problem i.e connection close.

yadnik17
 
Posts: 9
Joined: Sat Jun 08, 2019 10:46 am

Re: Regarding Publish Subscribe

by brubell on Thu Jul 11, 2019 9:35 am

yadnik17 wrote:Hello sir,
After pinging the server, still showing the same problem i.e connection close.




The mqtt_fona example is working for my fonna perfectly as it only sends integer value(counter value) and when any subscription appears it toggle led, depending on ON or OFF condition.


Does this example also close connection with the server?

Does the client show up on your monitor page under Connections as connected, and then as disconnected?
http://io.adafruit.com/monitor

brubell
 
Posts: 469
Joined: Fri Jul 17, 2015 10:33 pm

Re: Regarding Publish Subscribe

by yadnik17 on Thu Jul 11, 2019 10:43 am

No, the matt_fona example working perfectly for me.
Today I also try the code which is given by you i.e pinging the server, that also works perfectly.

What I did, I just keep subscription code listen to only onoff feed and added ping code to stay connected with the server. As soon as I toggle my onoff feed from a server, depending on that condition LED also toggle which is connected to Arduino. Up to this part all code working perfectly.

But when I try to send 'string', the connection is close by the server and Arduino start code from the beginning.
I also tried the code which is suggested by you to send 'string' but the problem is same i.e connection close.
I don't know why it happens?

On the serial monitor of Arduino, when 'connect' function run by the controller it shows " connected OK" and when string array is published by the server at that time connection is close by the server.

Your any help is appreciable.
Thank you.

yadnik17
 
Posts: 9
Joined: Sat Jun 08, 2019 10:46 am

Re: Regarding Publish Subscribe

by brubell on Thu Jul 11, 2019 4:56 pm

But when I try to send 'string', the connection is close by the server and Arduino start code from the beginning.
I also tried the code which is suggested by you to send 'string' but the problem is same i.e connection close.
I don't know why it happens?


Ok - I have a better idea of what's happening. Thanks for the explanation. The issue is the string packet being sent to Adafruit IO is malformed, and the Adafruit IO MQTT broker is closing its connection with your FONA when that occurs.

Could you post the complete code which is disconnecting you from Adafruit IO, within code blocks
Code: Select all | TOGGLE FULL SIZE
[code][/code]

brubell
 
Posts: 469
Joined: Fri Jul 17, 2015 10:33 pm

Re: Regarding Publish Subscribe

by abachman on Thu Jul 11, 2019 5:24 pm

hi yadnik17,


you're being disconnected because you're publishing to an invalid MQTT topic, it looks like.

Adafruit IO limits the topics you can publish to. You can find the valid topic for a particular feed by visiting the feed's home page, e.g., https://io.adafruit.com/abachman/feeds/active.temperature, and clicking on the "Feed Info" link at the top right corner of the page when you're logged in.

Valid MQTT topics are in the form of {username}/feeds/{feed_key} where "username" is your username and "feed_key" is the feed's key. NOTE: the feed key is unrelated to dashboard blocks. Dashboard block names are for display / identification purposes only and unrelated to the identification of the feeds they show.

You can see some more information about MQTT topics in the MQTT API documentation here: https://io.adafruit.com/api/docs/mqtt.html#mqtt-topics


- adam b.

abachman
 
Posts: 319
Joined: Mon Feb 01, 2010 12:48 pm

Re: Regarding Publish Subscribe

by yadnik17 on Fri Jul 12, 2019 4:01 am

Hello sir,
Thank you for your reply. I am giving my code on which I am working, please let me know where I am going wrong.

/***************************************************
5th July 2019
Sending string to Adafruit IO server.
****************************************************/
#include <Adafruit_SleepyDog.h>
#include <SoftwareSerial.h>
#include "Adafruit_FONA.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_FONA.h"

/*************************** FONA Pins ***********************************/

// Default pins for Feather 32u4 FONA
#define FONA_RX 2 // rx of fonna to rx of arduino
#define FONA_TX 3 // tx of fonna to tx of arduino
#define FONA_RST 4
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

/************************* WiFi Access Point *********************************/

// Optionally configure a GPRS APN, username, and password.
// You might need to do this to access your network's GPRS/data
// network. Contact your provider for the exact APN, username,
// and password values. Username and password are optional and
// can be removed, but APN is required.
#define FONA_APN "airtelgprs.com"
#define FONA_USERNAME ""
#define FONA_PASSWORD ""

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

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

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

// Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
Adafruit_MQTT_FONA mqtt(&fona, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

// You don't need to change anything below this line!
#define halt(s) { Serial.println(F( s )); while(1); }

// FONAconnect is a helper function that sets up the FONA and connects to
// the GPRS network. See the fonahelper.cpp tab above for the source!
boolean FONAconnect(const __FlashStringHelper *apn, const __FlashStringHelper *username, const __FlashStringHelper *password);

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

// Setup a feed called 'console' for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>

// Stream window is created on server and name it as "console".
Adafruit_MQTT_Publish console = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/console");// publish feed

// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");

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

// How many transmission failures in a row we're willing to be ok with before reset
uint8_t txfailures = 0;
#define MAXTXFAILURES 3
const int led = 12;
char mystring[20] = "Hello everyone";
/*************************** Setup Area ******************************/

void setup()
{
while (!Serial);

pinMode(led, OUTPUT); //---------- led will toggle depending on status of onoff feed from the server
// Watchdog is optional!
// Watchdog.enable(8000);

Serial.begin(115200);

Serial.println(F("Adafruit FONA MQTT demo"));

mqtt.subscribe(&onoffbutton);

Watchdog.reset();
delay(5000); // wait a few seconds to stabilize connection
Watchdog.reset();

// Initialise the FONA module
while (! FONAconnect(F(FONA_APN), F(FONA_USERNAME), F(FONA_PASSWORD)))
{
Serial.println("Retrying FONA");
}

Serial.println(F("Connected to Cellular!"));

Watchdog.reset();
delay(5000); // wait a few seconds to stabilize connection
Watchdog.reset();
}



//****************************** Main code ***************************************

void loop()
{
// Make sure to reset watchdog every loop iteration!
Watchdog.reset();

// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
MQTT_connect();

Watchdog.reset();

// this is our 'wait for incoming subscription packets' busy subloop.......................................
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000)))
{
if (subscription == &onoffbutton)
{
Serial.print(F("Got: "));
Serial.println((char *)onoffbutton.lastread);

if (strcmp((char *)onoffbutton.lastread, "ON") == 0) { digitalWrite(led, HIGH); delay(1000); }
else if (strcmp((char *)onoffbutton.lastread, "OFF") == 0) { digitalWrite(led, LOW); delay(1000); }
else { /* come here and dont do anything....*/}
}

}

// Now we can publish stuff!................................................................................

console.publish(AIO_USERNAME "/feeds/console",mystring);
// delay(200);




// ping the server to keep the mqtt connection alive, only needed if we're not publishing
// if(! mqtt.ping())
// {
// Serial.println(F("MQTT Ping failed."));
// }

}

//==============================================================

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect()
{
int8_t ret;

// Stop if already connected.
if (mqtt.connected())
{
return;
}

Serial.print("Connecting to MQTT... ");

while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
{
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
}

Serial.println("MQTT Connected!");
}

The fonahelper.cpp file is already present in the mqtt_fonna example so I am not providing that code here.
Is I am passing a different parameter to publish function or anything else? This code is working perfectly when I keep only the subscription code and pinging the server to stay connected.
But when I add publish() code server closes the connection and Arduino start to execute code from the beginning.
Please, suggest me what going wrong in the code? Your any help is appreciable.
Thank you.
Last edited by yadnik17 on Sun Jul 14, 2019 3:14 pm, edited 1 time in total.

yadnik17
 
Posts: 9
Joined: Sat Jun 08, 2019 10:46 am

Please be positive and constructive with your questions and comments.