MQTT losing server connection

Stumpy_L
Posts: 10
Joined: Fri Feb 04, 2022 3:50 pm

MQTT losing server connection

Postby Stumpy_L » Wed Nov 01, 2023 8:11 am

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 the 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.

Code: Select all

/*********
  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, (timeStamp).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 suggestions and comments
John

lbernstone
Posts: 829
Joined: Mon Jul 22, 2019 3:20 pm

Re: MQTT losing server connection

Postby lbernstone » Wed Nov 01, 2023 1:04 pm

You may be getting interference. Make sure the WiFi antenna is completely exposed above and below for the best reception. Have the LORA antenna pointing out the opposite direction. Turn on verbose debug level and see if it gives you any indication why it is disconnecting. You can set up an event on the disconnection and print something to serial to see if it is correlated with a specific action the device is performing. https://github.com/espressif/arduino-es ... Events.ino

Stumpy_L
Posts: 10
Joined: Fri Feb 04, 2022 3:50 pm

Re: MQTT losing server connection

Postby Stumpy_L » Wed Nov 01, 2023 4:37 pm

Right now the ESP32 is laying on a breadboard, the Lora antenna is on a small angle bracket a few inches away and about an inch or so higher than the ESP. I'll try to reposition them both. I'll look into setting up the debug.

Thanks for the suggestions

Who is online

Users browsing this forum: No registered users and 75 guests