Adafruit Industries, Essential service and business: NYC – Executive Order 202.6 - Read more.
0

Disconnect to the server when subscribe
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.
Please be positive and constructive with your questions and comments.

Disconnect to the server when subscribe

by RuiT on Tue Mar 03, 2020 1:07 pm

Dear all,

Thanks in advanced for those who read this. Sorry to bother you guys, but I haven't found any similar topics.

I connect my Teensy3.6 to a Feather board to talk to the server via Ethernet.
I can succesfully connect to the server but I have trouble in subscription.
The problem is described below:
When I change the on/off button on the dashboard(do a subscription), Only 10% times that I can succesfully get corresponding reaction in my board but in the other 90% time,
I disconnect to the server and try to reconnect,

The code is from the example of Arduino IDE, I just change to Ethernet instead of WIFI connection.


Code: Select all | TOGGLE FULL SIZE
#include <Ethernet.h>                              // INcluding header file for Ethernet(How the connection works)
#include <EthernetClient.h>                    // Including header file for Ethernet(Client information like ID)
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME  "************"            //  I have it in my code, but for safety, I don't show the Username but it shouldn't have any problem.
#define AIO_KEY       "***********"                     //  I have it in my code, but for safety, I don't show the key but it shouldn't have any problem.

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };       //Ethernet hardware address
EthernetClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

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

// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
Adafruit_MQTT_Subscribe slider = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/slider");

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

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(PWMOUT, OUTPUT);
  pinMode(CS_Ethernet, OUTPUT);   // Chip Select for Ethernet Module in port 25
   
  Serial.begin(115200);
  delay(10);

    Ethernet.init(CS_Ethernet);                // Initialize Ethernet communication
    Ethernet.begin(mac);                       // Start Ethernet communication
    delay(1000);                               // Give the ethernet a second(1000ms) to initialize
    int Con_Test = mqtt.connect();
    Serial.print(Con_Test);

  // Setup MQTT subscription for onoff & slider feed.
  mqtt.subscribe(&onoffbutton);
  mqtt.subscribe(&slider);
}

uint32_t x=0;

void loop() {
  // 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();

  // this is our 'wait for incoming subscription packets' busy subloop
  // try to spend your time here

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    // Check if its the onoff button feed
    if (subscription == &onoffbutton) {
      Serial.print(F("On-Off button: "));
      Serial.println((char *)onoffbutton.lastread);
     
      if (strcmp((char *)onoffbutton.lastread, "ON") == 0) {
        digitalWrite(LED, LOW);
      }
      if (strcmp((char *)onoffbutton.lastread, "OFF") == 0) {
        digitalWrite(LED, HIGH);
      }
    }
   
    // check if its the slider feed
    if (subscription == &slider) {
      Serial.print(F("Slider: "));
      Serial.println((char *)slider.lastread);
      uint16_t sliderval = atoi((char *)slider.lastread);  // convert to a number
      analogWrite(PWMOUT, sliderval);
    }
  }

  // ping the server to keep the mqtt connection alive
  if(! mqtt.ping()) {
    mqtt.disconnect();
  }

}

// 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... ");

  uint8_t retries = 3;
  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
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}



Thanks again.
Rui

RuiT
 
Posts: 3
Joined: Wed Feb 19, 2020 11:39 am

Re: Disconnect to the server when subscribe

by RuiT on Wed Mar 04, 2020 10:41 am

Hi all, I worked on this today as well.
I found that everytime when the main loop runs for 3 time, the discconection happens, then it will automaticly reconnect, then 3 more loops, then disconnect again and it goes on.
But when I do the subscription, it will work or disconnect directly.

One more strange thing about subscription function:

while ((subscription = mqtt.readSubscription(5000)))

This function is for detecting subscription which should keep detecting for 5 seconds.
After this function started to detect subscription message, the earler I do the subscription, the higher possibility it will work.
It makes really big difference if I do it in the first second(almost all the times succesful) or the last 2 seconds inside these 5 seconds(nearly no chance to work).
I have no clue that where the problem is and which direction shall I work on.

RuiT
 
Posts: 3
Joined: Wed Feb 19, 2020 11:39 am

Re: Disconnect to the server when subscribe

by brubell on Wed Mar 04, 2020 12:49 pm

Hi RuiT,

I found that everytime when the main loop runs for 3 time, the discconection happens, then it will automaticly reconnect, then 3 more loops, then disconnect again and it goes on.


It's possible that you're incorrectly subscribing or publishing to these two feeds, and it's disconnecting you from Adafruit IO.

Check the monitor page while your code is running, it'll output any errors you may have: http://io.adafruit.com/monitor

Next, does your serial monitor output any of the messages in your loop, such as: "On-off button" or "Slider"?

Could you modify the ping code in your code to my code below, it'll help me detect if it's disconnecting here:
Code: Select all | TOGGLE FULL SIZE
  if(! mqtt.ping()) {
    Serial.println("*Disconnecting!");
    mqtt.disconnect();
  }


Then, could you copy and paste the output of your serial monitor in your reply below? It will help me debug your code.

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

Re: Disconnect to the server when subscribe

by RuiT on Thu Mar 05, 2020 12:49 pm

Hi brubell,
Thanks for your help at first!
I put the result from my serial monitor into the code window here to explain what happens.
It does not bother me very much when the connection failed, I just need to catch the timing or try more times, it sends the subscription anyway.
Today I get one thing weird: after I start the teensy, the loop is running and it keeps publishing without any problem, I can see the stars" *** " goes on and on in my serial monitor and data sent to the server monitor, but when I try to do a subscription, nothing happens, I do not get it in my serial monitor and the connection does not break down either, just like I did not do it.
Only when I see in my serial monitor something like "disconnect" and "MQTT Connected" or only "MQTT Connected", the subscription seems to be activated and I can receive subscription with "automatic disconnected" problems.
Do you have any idea why the Subscription needs to be activated by reconnecting? I added the disconnect and connect function in my setup but it makes no difference.


Code: Select all | TOGGLE FULL SIZE
**Disconnecting   [b]// I put this "Serial.print("*");" before the subscription command to see when it is the time for it to read the subscription message.[/b]
MQTT Connected!
**On-Off button: ON     [b] // Success because I send the subscribe from the Server monitor once I see the star[/b]
*On-Off button: OFF      // Success
*Disconnecting              [b]// Failed because I wait for about 1 Second before I send the subscription[/b]
MQTT Connected!
*On-Off button: OFF
*Disconnecting
MQTT Connected!       
***Disconnecting           [b]// If I do not subscribe, it breaks automatically every 2 or 3 loops(yesterday was fixed every 3 loops)[/b]
MQTT Connected!
**Disconnecting
MQTT Connected!
***Disconnecting
MQTT Connected!
**Disconnecting
MQTT Connected!
********************


I hope I describe my question and the situation clear because it is really not even logical for me...… Please let me know if I did not make it clear somewhere. >.<
Thanks again!
Rui
Attachments
Wifi1.PNG
Wifi1.PNG (11.19 KiB) Viewed 28 times

RuiT
 
Posts: 3
Joined: Wed Feb 19, 2020 11:39 am

Please be positive and constructive with your questions and comments.