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