Hey everyone, I have a quite a weird problem here. It seems to be a combination of problems that other people have had. I'll explain it below.
I have connected an Arduino UNO R4 WiFi to Mosquitto running on Docker in my VM and it used to work fine for weeks. Suddenly, there seems to be an issue where the Arduino connects to the MQTT broker once, but then it doesnt for a few hours. I know my program works as I have used it before countless times.
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>
// WiFi credentials
#define SECRET_SSID "ABC"
#define SECRET_PASS "XYZ"
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "10.xxx.xxx.xxx";
int port = 1883;
// MQTT Topics
const char* topic1 = "sensors/mockdata1";
const char* topic2 = "sensors/mockdata2";
const char* topic3 = "sensors/mockdata3";
const char* topic4 = "sensors/mockdata4";
const char* topic5 = "sensors/mockdata5";
const char* topic6 = "sensors/mockdata6";
int status = WL_IDLE_STATUS;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("Connecting to WiFi...");
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("WiFi module not found!");
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the WiFi firmware.");
}
while (status != WL_CONNECTED) {
Serial.print("Connecting to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(1000);
}
Serial.println("WiFi connected.");
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("MQTT connected.");
}
void loop() {
// Reconnect to MQTT if disconnected
if (!mqttClient.connected()) {
Serial.println("MQTT disconnected! Attempting reconnection...");
if (!mqttClient.connect(broker, port)) {
Serial.println("MQTT reconnection failed");
delay(1000);
return;
} else {
Serial.println("MQTT reconnected!");
}
}
mqttClient.poll();
//publishTopic1();
//publishTopic2();
//publishTopic3();
//publishTopic4();
//publishTopic5();
//publishTopic6();
delay(1000); // Delay between publish rounds
}
// -------- Sensor Publish Functions --------
void publishTopic1() {
// Sensor 1 logic here
// ...
mqttClient.beginMessage(topic1);
mqttClient.print("1"); // Simulated sensor data
mqttClient.endMessage();
}
void publishTopic2() {
// Sensor 2 logic here
// ...
mqttClient.beginMessage(topic2);
mqttClient.print("2"); // Simulated sensor data
mqttClient.endMessage();
}
void publishTopic3() {
// Sensor 3 logic here
// ...
mqttClient.beginMessage(topic3);
mqttClient.print("3"); // Simulated sensor data
mqttClient.endMessage();
}
void publishTopic4() {
// Sensor 4 logic here
// ...
mqttClient.beginMessage(topic4);
mqttClient.print("4"); // Simulated sensor data
mqttClient.endMessage();
}
void publishTopic5() {
// Sensor 5 logic here
// ...
mqttClient.beginMessage(topic5);
mqttClient.print("5"); // Simulated sensor data
mqttClient.endMessage();
}
void publishTopic6() {
// Sensor 6 logic here
// ...
mqttClient.beginMessage(topic6);
mqttClient.print("6"); // Simulated sensor data
mqttClient.endMessage();
}
I then use the next program to check if the Arduino is getting a dynamically assigned IP address once I connect to the WiFi:
#include "WiFiS3.h"
// WiFi credentials
#define SECRET_SSID "ABC"
#define SECRET_PASS "XYZ"
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
int status = WL_IDLE_STATUS;
void setup() {
Serial.begin(9600);
while (!Serial) {
; // Wait for serial port to connect (needed for native USB)
}
Serial.println("Connecting to WiFi...");
// Check for WiFi module
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
while (true); // Do not proceed
}
// Firmware check
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the WiFi firmware.");
}
// Attempt to connect
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(5000);
}
Serial.println("Connected to WiFi!");
// Print IP address
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// Print MAC address
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC Address: ");
for (int i = 0; i < 6; i++) {
if (mac[i] < 16) Serial.print("0");
Serial.print(mac[i], HEX);
if (i < 5) Serial.print(":");
}
Serial.println();
}
void loop() {
// Nothing needed here
}
This program also works perfectly.
The issue is, after a few hours of inactivity with MQTT or the next day, when I use the IP address finder program, it gives me the correct dynamically assigned IP address.
I then use the MQTT program to send data to my VM; however the Arduino only connects once and then the IP address is dynamically set to 0.0.0.0.
MQTT then doesnt work for the rest of the day pretty much and the IP address is then also 0.0.0.0 during that time.
I have tried this with multiple Arduinos and I get the same result.
Does anyone have any clue of what could be the issue?
Other details:
-Firewall is not an issue, everything has access
-Wifi router is 2.4GHz
-If I use my phone WiFi, I can connect to a public mqtt broker such as hivemqtt
-I have tried assigning a static IP address, it also does not work
- The error I get when MQTT does not work is rc = -2
