knolleary / pubsubclient

A client library for the Arduino Ethernet Shield that provides support for MQTT.
http://pubsubclient.knolleary.net/
MIT License
3.83k stars 1.47k forks source link

Implementing client.connected() check or client.loop() breaks other parts of program. #694

Open Arcires opened 4 years ago

Arcires commented 4 years ago

Hi there,

I'm working on a project where I want to connect a Controllino with an ESP8266-01 WiFi module. I can successfully connect to a WiFi and connect to a local (C#-based) broker on that WiFi. Both the PubSubClient and the broker confirms this.

However, I have run into an issue when I want to check for new messages and renew the connection (via mqttClient.loop()) in the void loop method. Likewise, if I want to check the current connectivity state (mqttClient.connected()), my WiFi connectivity stops working entirely, and I am no longer able to connect to the WiFi.

#include <PubSubClient.h>
#include <WiFiEsp.h>
#include <Controllino.h>  //Baseline Controllino library. Mandatory in order to use CONTROLLINO_xx aliases for pins in sketch.

//WiFi credentials, and Broker information.
char ssid[] = "XXXXX";            // Network SSID (name)
char pass[] = "xxxxxx!";        // Network password
int status = WL_IDLE_STATUS;     // the WiFi radio's status

char serverIP[] = "192.168.43.40";
int portNumber = 1883;
//char macArrayToSend[6]; For later use

//Setting up arrays for easier management of leds and buttons.
int buttonLEDs[] = {CONTROLLINO_D0, CONTROLLINO_D1, CONTROLLINO_D2, CONTROLLINO_D3, CONTROLLINO_D4, CONTROLLINO_D5, CONTROLLINO_D6, CONTROLLINO_D7, CONTROLLINO_D8};
int buttonAnalog[] = {CONTROLLINO_A0, CONTROLLINO_A1, CONTROLLINO_A2, CONTROLLINO_A3, CONTROLLINO_A4, CONTROLLINO_A5, CONTROLLINO_A6, CONTROLLINO_A7, CONTROLLINO_A8};

//WiFi Client. Used to establish connection to local WiFi
WiFiEspClient espClient;

//MQTT Client
PubSubClient mqttClient(serverIP, portNumber, espClient);

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]);
  }
  Serial.println();
}

//----------* Functions *---------//
void setupMQTTClient(){
  Serial.println("[MQTT] Attempting to connect to broker...");

  mqttClient.setCallback(callback);
  bool connectionResult = mqttClient.connect("CONTROLLINO", "superSecretUN", "superSecretPW");

  Serial.print("[MQTT] Connection result: ");
  Serial.println(connectionResult);

  while (!connectionResult){
    Serial.println("[MQTT] Connection failed!");
    delay(1500);
    connectionResult = mqttClient.connect("CONTROLLINO", "superSecretUN", "superSecretPW");
  }

  if (connectionResult){
    Serial.println("[MQTT] Connection established!");
    Serial.println("[MQTT] Subscribing to topic...");
    //mqttClient.subscribe("CONTROLLINO", 1); //Breaks the program
  }
}

void setupWiFi(){
  WiFi.init(&Serial2); //Initialize connection via Serial2.

  if (WiFi.status()==WL_NO_SHIELD){
    Serial.println("WiFiEsp] WiFi shield not present");
    while(true);
  }

  while (status != WL_CONNECTED) {
    Serial.print("[WiFiEsp] Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }
  Serial.println("[WiFiEsp] WiFi connection established!");
  Serial.print("WIFI Status: ");
  Serial.println(status);

}

//Turns on a button LED and waits for button press before continuing.
bool turnOnButton(int input){
  if (input > 24){ //Edge cases where designated LED does not exist in PLC.
    return false;
  }
  if (input == -1){ //Edge case where a reset of all LEDs is requested.
    for (int i = 0; i < sizeof(buttonLEDs); i++){
      digitalWrite(buttonLEDs[i], LOW);
    }
    return true;
  }
  else{
    //Turn on LED
    digitalWrite(buttonLEDs[input], HIGH);

    while(digitalRead(buttonAnalog[input])== LOW){
      //Keep waiting for the user to push the button.
    }
    //The button has been pushed down by the user.
    Serial.println("Button pushed");
    digitalWrite(buttonLEDs[input], LOW);
    return true;                
  }
}

void printWifiStatus()
{
  //Print the SSID of the network currently connected to.
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  //Print WiFi module's IP address.
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  //Print WiFi module's MAC address.
  byte mac[6]={0,0,0,0,0,0};
  WiFi.macAddress(mac);
  Serial.print("MAC Address: ");
    Serial.print(mac[5], HEX);
    Serial.print(":");
    Serial.print(mac[4], HEX);
    Serial.print(":");
    Serial.print(mac[3], HEX);
    Serial.print(":");
    Serial.print(mac[2], HEX);
    Serial.print(":");
    Serial.print(mac[1], HEX);
    Serial.print(":");
    Serial.println(mac[0], HEX);

  //Print the received signal strength.
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

//Set up pins and LEDS using arrays.
void setupPins(){
  Serial.println("[CONTROLLINO] Setting up pins...");
  for (int i = 0; i < sizeof(buttonLEDs); i++){ 
    //Set up LED pins.
    pinMode(buttonLEDs[i], OUTPUT);
    digitalWrite(buttonLEDs[i], LOW);
    //Set up analog pins.
    pinMode(buttonAnalog[i], INPUT);
  }
  Serial.println("[CONTROLLINO] Pin setup succeeded");
}

void testButton(int input){
  bool test = false;
  Serial.print("Testing button: ");
  Serial.println(input);

  test = turnOnButton(input);
  if (test == true){
    Serial.println("Button succeeded");
  }else{
    Serial.println("Button failed");
  }
}
//----------* End of Functions *---------//

void setup() {
  Serial.begin(9600); //Regular serial printout to COM
  Serial2.begin(115200); //Serial connection to ESP8266 WiFi module

  setupPins();

  setupWiFi();

  printWifiStatus();

  setupMQTTClient();
}

void loop() {
  //mqttClient.loop() Breaks the program
}

Any help would be greatly appreciated, as I am at my wits end trying to get it to work 😢

Psykozis commented 4 years ago

Hello! I have some problem like you, mine don't disconect to the wifi, only from the broker. I isolate the problem in my case, and i have problem to use analog input... try to comment every part where you use this and verify if this continues... if not, the problems maybe the same...

https://github.com/knolleary/pubsubclient/issues/725

Arcires commented 4 years ago

Hi @Psykozis,

Thank you for the reply, and the link to your own problem. I've tried a number of things, including commenting, reimplementing the entire project, tried compiling and running on a separate platform, etc. None of which seems to work.

I am not sure if our problems are the exact same structurally, but as others have commented in your issue, it seems to stem from ressource hogging in your program. It might be the same issue in my program. Sadly, I am not able to test it, as I no longer posses the equipment necessary :disappointed:

thijsdebont commented 4 years ago

I'm not familiar with the controllino boards. But are you programming the ESP itself with the sketch? If so, is an unknown to me. Have you tried your sketch with the lib?