MQTT losing connection

I’m working on a Lora system, I have a sending unit using a Sparkfun Firebeetle with a BME280 sensor. That sends the values to a the base unit in my house using a ESP32 Dev module. That part is working fine. I’ve now added MQTT to the base unit. I have a Raspberry Pi 4 server running Mosquitto and using Node-Red to display the data. This part also for the most part is working.

The problem seems to be that I keep losing the connection to the server. I had found an example program that checks if the MQTT connection is still there, if not it reconnects, happens about every minute. If I use a program that does not have Lora I can send data to the server without losing the connection.

I’m not sure if something in the code is causing the problem or if there is a hardware, pin definition conflict. here is the code I am running.

  Rui Santos
  Complete project details at  
  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
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 ""
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

  // 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)) {
  // 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
  Serial.println("LoRa Initializing OK!");

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

  // Initialize a NTPClient to get time
  // 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
  if (!SD.begin(SD_CS)) {
    Serial.println("Card Mount Failed");
  uint8_t cardType = SD.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
  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 ="/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");

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

}  // end setup

void loop() {

  if (!client.connected()) {

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

}  // end loop

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

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

// 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

    // 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.print("Humdity = ");
    Serial.print("Pressure = ");
    Serial.print("Battery = ");
  // Get RSSI
  rssi = LoRa.packetRssi();
  Serial.print(" with 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, (timeStamp).c_str(),true);

}  // end getloroadata

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

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

// 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 =, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");

// 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 =, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");

Thanks for all suggestions and comments.

Shouldn’t mqttclient.loop() be called in loop() ?