Hi all,
Below is the code I am running on a RP2040 Nano Connect.
A brief description of my code:
void loop()
- If pin A3 is HIGH, pin 8 and pin 6 will switch HIGH. If pin A3 goes LOW, a delay timer(using millis) is activated to switch pin 8 LOW and successively activate another delay timer(using millis) to switch pin 6 LOW. The above can be considered as a critical task, hence should be executed regardless of Wifi and/or MQTT broker connection status.
void tele()
- Non critical task, responsible for Wifi & MQTT connection and publishing values of pin A3, 6 & 8.
To achieve the expected outcome, I used the Scheduler library(Scheduler.h)
which requires delay()
& yield()
to switch between tasks.
The issue I am having, it publishes MQTT messages for 30-40mins on average after which it stops publishing until a reboot.
I tried digging the internet for causes/solutions but could not find any regarding this problem. I am suspecting it might be related to the global structure of the code.
Has anyone encountered similar issue while publishing MQTT messages?
Actually, I am open to all suggestions even if it requires changing the entire structure of the code. Improvement regarding the overall efficiency of the code will also be appreciated.
Looking forward to the community's input.
Thank you.
#include <Scheduler.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoMqttClient.h>
#include "arduino_secrets.h"
const int PSON = A3; // Voltage detection
const int SSR = 8; // Solid State Relay control
const int FAN = 6; // Fan control
unsigned long ssrTimer = 0; // SSR timer
unsigned long fanTimer = 0; // fan timer
int psState = 0; // PSON status
int ssState = 0; // SSR status
int fnState = 0; // FAN status
//Enter data in secret tab(arduino_secrets.h)
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "10.0.0.10";
int port = 1883;
const char topic[] = "RP2040Nano/PSon";
const char topic2[] = "RP2040Nano/SSR";
const char topic3[] = "RP2040Nano/FAN";
void setup() {
Serial.begin(9600);
pinMode(PSON, INPUT); // analog pin A3 as input
pinMode(SSR, OUTPUT); // digital pin 8 as output
pinMode(FAN, OUTPUT); // digital pin 6 as output
digitalWrite(SSR, LOW);
digitalWrite(FAN, LOW);
// attempt to connect to WiFi network:
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
if (WiFi.begin(ssid, pass) != WL_CONNECTED) {
Serial.println("You're not connected to the network");
Serial.println();
}
else {
Serial.println("You're connected to the network");
Serial.println();
}
// You can provide a username and password for authentication
mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
}
else {
Serial.println("You're connected to the MQTT broker!");
Serial.println();
}
Scheduler.startLoop(tele);
}
void loop() {
psState = analogRead(PSON); // read analog input
ssState = digitalRead(SSR); // read digital output
fnState = digitalRead(FAN); // read digital output
if (psState > 50)
ssrTimer = 100; // delay SSR for 10 seconds
psOFF(); // run psOFF
if (ssState == 1)
fanTimer = 100; // delay Fan for 10 seconds
fnOFF(); // run psOFF
delay(100);
}
void psOFF()
{
static unsigned long sspreviousTime;
unsigned long sscurrentTime = millis(); // return time since board active
if (sscurrentTime - sspreviousTime < 100) // move forward if 100 ms has elapsed
return;
sspreviousTime = sscurrentTime;
if (!ssrTimer) {
digitalWrite(SSR, LOW); // if timer is done or still 0, set digital output LOW
}
else {
digitalWrite(SSR, HIGH); // set digital output HIGH
digitalWrite(FAN, HIGH); // set ditigal output HIGH
ssrTimer--;
}
}
void fnOFF()
{
static unsigned long fnpreviousTime;
unsigned long fncurrentTime = millis(); // return time since board active
if (fncurrentTime - fnpreviousTime < 100) // move forward if 100 ms has elapsed
return;
fnpreviousTime = fncurrentTime;
if (!fanTimer) {
digitalWrite(FAN, LOW); // if timer is done or still 0, set digital output LOW
}
else {
digitalWrite(FAN, HIGH); // set digital output HIGH
fanTimer--;
}
}
void tele(){
if (WiFi.status() != WL_CONNECTED) {
// Wifi disconnected, connect
connectWiFi();
}
// call poll() regularly to allow the library to send MQTT and prevent disconnection by the broker
mqttClient.poll();
static unsigned long previousMillis;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 5000) {
// save the last time a message was sent
previousMillis = currentMillis;
if (!mqttClient.connected()) {
// MQTT client is disconnected, connect
connectMQTT();
}
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic);
mqttClient.print(psState);
mqttClient.endMessage();
mqttClient.beginMessage(topic2);
mqttClient.print(ssState);
mqttClient.endMessage();
mqttClient.beginMessage(topic3);
mqttClient.print(fnState);
mqttClient.endMessage();
}
yield();
}
void connectWiFi() {
WiFi.end();
Serial.print("Attempting to connect to SSID: ");
Serial.print(ssid);
Serial.println();
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println();
Serial.println("You're connected to the network");
Serial.println();
}
void connectMQTT() {
mqttClient.stop();
Serial.print("Attempting to MQTT broker: ");
Serial.print(broker);
Serial.println();
while (!mqttClient.connect(broker, port)) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println();
Serial.println("You're connected to the MQTT broker");
Serial.println();
}