MQTT keeps reconnecting

I have 2 ESP32 LoRa nodes, one has a BME280, sending the values to the other node, I'll call the base unit as it's in the house, that has worked fine. I'm now trying to connect that unit to a MQTT server. I have a raspberry pi 4 running mosquito, I'm also using Node Red on my laptop and have that connected to the server with the data showing on the Node Red dashboard. I was having troubles getting the data to Node Red. I have another program, that is simpler and doesn't have the Lora code. It's just a incrementing value, that I can send to Node Red no problem. I had gotten that code of off a YouTuber. Using that code for my other program he has a reconnect function so if the MQTT is not connected it reconnects.

That appears to have been my problem, I was losing the MQTT connection. Now that I have added that function, MQTT gets connected but then for some reason I lose the connection and it reconnects and so on and so on. The other code stays connected.

I'm assuming there is some conflict between the LoRa set up and the MQTT or I just don't have something in the MQTT set properly. I've try many modifications but can't seem to find why.

That's the question, why does the MQTT keep losing it's connection?

Here is the code:

/*********
  Rui Santos
  Complete project details at http://randomnerdtutorials.com  
  Rev 2 added barometric pressure
  Rev 3 moved HTML code to separate tab, will delete later
  Rev 4 Added MQTT client
*********/

// Import libraries
#include <WiFi.h>
#include <SPI.h>
#include <LoRa.h>

// Libraries to get time from NTP Server
#include <NTPClient.h>
#include <WiFiUdp.h>

// Libraries for SD card
#include "FS.h"
#include "SD.h"

// Replace with your network credentials
const char* ssid = "Fios-tCL9H";
const char* password = "PamPolly_1155";

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;

// LoRa Module pin definition
// define the pins used by the LoRa transceiver module
#define ss 5
#define rst 14
#define dio0 2

// Initialize variables to get and save LoRa data
int rssi;
String loRaMessage;
String temperature;
String soilMoisture;
String batteryLevel;
String readingID;
String Humidity;
String pressure;

// Define CS pin for the SD card module
#define SD_CS 22

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

//MQTT Setup Start
#include <PubSubClient.h>
#define mqtt_server "192.168.1.171"
WiFiClient espClient;
PubSubClient client(espClient);
#define mqttTemp1 "greenHouse/temp1"
#define mqttHum1 "greenHouse/hum1"
#define mqttPrss1 "greenHouse/prss1"
#define mqttBatt1 "greenHouse/batt1"
#define mqttTime "greenHouse/time"
//MQTT Setup End

void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);

  // Initialize LoRa
  //replace the LoRa.begin(---E-) argument with your location's frequency
  //note: the frequency should match the sender's frequency
  //433E6 for Asia
  //866E6 for Europe
  //915E6 for North America
  LoRa.setPins(ss, rst, dio0);
  while (!LoRa.begin(915E6)) {
    Serial.println(".");
    delay(500);
  }
  // Change sync word (0xF3) to match the sender
  // The sync word assures you don't get LoRa messages from other LoRa transceivers
  // ranges from 0-0xFF
  LoRa.setSyncWord(0xF3);
  Serial.println("LoRa Initializing OK!");

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();

  // Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(-14400);  // 3600

  // Initialize SD card
  SD.begin(SD_CS);
  if (!SD.begin(SD_CS)) {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }
  Serial.println("Initializing SD card...");
  if (!SD.begin(SD_CS)) {
    Serial.println("ERROR - SD card initialization failed!");
    return;  // init failed
  }

  // If the data.txt file doesn't exist
  // Create a file on the SD card and write the data labels
  File file = SD.open("/data.txt");
  if (!file) {
    Serial.println("File doens't exist");
    Serial.println("Creating file...");
    writeFile(SD, "/data.txt", "Reading ID, Date, Hour, Temperature, Humidity (0-100), RSSI, Battery Level(0-100)\r\n");
  } else {
    Serial.println("File already exists");
  }
  file.close();

  // MQTT connection
  client.setServer(mqtt_server, 1883);

}  // end setup

void loop() {

  if (!client.connected()) {
    Serial.println("reconnect()");
    reconnect();
  }

  // Check if there are LoRa packets available
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    getLoRaData();
    getTimeStamp();
    logSDCard();
  }
  WiFiClient client = server.available();  // Listen for incoming clients

  //delay(5000);

}  // end loop

void reconnect() {
  // Loop until we're reconnected
  int counter = 0;
  while (!client.connected()) {
    if (counter == 5) {
      ESP.restart();
    }
    counter += 1;
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect

    if (client.connect("greenHouseController")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// Read LoRa packet and get the sensor readings
void getLoRaData() {
  Serial.print("Lora packet received: ");
  // Read packet
  while (LoRa.available()) {
    String LoRaData = LoRa.readString();
    // LoRaData format: readingID/temperature&soilMoisture#batterylevel
    // String example: 1/27.43&654#95.34
    Serial.print(LoRaData);

    // Get readingID, temperature and humidity
    int pos1 = LoRaData.indexOf('/');
    int pos2 = LoRaData.indexOf('&');
    int pos3 = LoRaData.indexOf('%');
    int pos4 = LoRaData.indexOf('#');
    readingID = LoRaData.substring(0, pos1);
    temperature = LoRaData.substring(pos1 + 1, pos2);
    Humidity = LoRaData.substring(pos2 + 1, pos3);
    pressure = LoRaData.substring(pos3 + 1, pos4);
    batteryLevel = LoRaData.substring(pos4 + 1, LoRaData.length());

    Serial.println(" ");
    Serial.print("Temp = ");
    Serial.println(temperature);
    Serial.print("Humdity = ");
    Serial.println(Humidity);
    Serial.print("Pressure = ");
    Serial.println(pressure);
    Serial.print("Battery = ");
    Serial.println(batteryLevel);
  }
  // Get RSSI
  rssi = LoRa.packetRssi();
  Serial.print(" with RSSI ");
  Serial.println(rssi);

  // publish to MQTT server
  client.publish(mqttTemp1, String(temperature).c_str(), true);
  client.publish(mqttHum1, String(Humidity).c_str(), true);
  client.publish(mqttPrss1, String(pressure).c_str(), true);
  client.publish(mqttBatt1, String(batteryLevel).c_str(), true);
  //client.publish(mqttTime, (myTime).c_str(),true);

}  // end getloroadata

// Function to get date and time from NTPClient
void getTimeStamp() {
  while (!timeClient.update()) {
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);

  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  Serial.println(dayStamp);
  // Extract time
  timeStamp = formattedDate.substring(splitT + 1, formattedDate.length() - 1);
  Serial.println(timeStamp);
}

// Write the sensor readings on the SD card
void logSDCard() {
  loRaMessage = String(readingID) + "," + String(dayStamp) + "," + String(timeStamp) + "," + String(temperature) + "," + String(Humidity) + "," + String(rssi) + "," + String(batteryLevel) + "\r\n";
  appendFile(SD, "/data.txt", loRaMessage.c_str());
}

// Write to the SD card (DON'T MODIFY THIS FUNCTION)
void writeFile(fs::FS& fs, const char* path, const char* message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

// Append data to the SD card (DON'T MODIFY THIS FUNCTION)
void appendFile(fs::FS& fs, const char* path, const char* message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

Thanks for all help and comments

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.