Hi.
I am using a mkr1010 board, with MKR ENV Shield. I use MQTT to send measure data to a RPI server. It measures every 3 minutos.
After aprox. 1-2 hours (I don't know the exact time), the orange led on the arduino board starts to blink. I run a MemoryFree library, and there is no memory leak.
Here my code
/*
ArduinoMqttClient - WiFi Sender
Reference:
https://create.arduino.cc/projecthub/officine-innesto/control-your-iot-cloud-kit-via-mqtt-and-node-red-114b4b?ref=user&ref_id=65561&offset=0
Connects to a MQTT broker and publishes a sensor data once a time.
*/
// https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoWiFi101/ArduinoWiFi101.ino
#include <MQTT.h>
// from https://github.com/mpflaga/Arduino-MemoryFree see also https://playground.arduino.cc/Code/AvailableMemory/
#include <MemoryFree.h>;
#include <pgmStrToRAM.h>; // not needed for new way. but good to have for reference.
#ifdef ARDUINO_SAMD_MKRWIFI1010
#include <WiFiNINA.h>
#define WIFILIB "WIFININA"
#elif ARDUINO_SAMD_MKR1000
#include <WiFi101.h>
#define WIFILIB "WIFI101"
#else
#error unknown board
#endif
#include "variables.h"
#include "Func_MKREnv.h"
#include "arduino_secrets.h"
#include "pm25sensor.h"
//#define BROKER_IP "192.168.1.44" // RPI4
//#define BROKER_IP "192.168.1.43" // RPI3
#define BROKER_IP "192.168.30.100" // RPI4_03 SensorServer
//#define BROKER_IP "192.168.1.52" // important: you have to change this to your IP brocker Addres
const char ssid[] = SECRET_SSID; // Network SSID (name)
const char pass[] = SECRET_PASS; // Network password (use for WPA, or use as key for WEP)
const int port = 1883;
String sendTopic = "/arduino/";
const int sensorId = 18;
String sensorLabel = "-";
long logInterval = 180000; // 300000: 5 minutes; 180000: 3 minutes
long lastMillis = -logInterval; // to start logging from beginning
// long int goes from -2147483648 to 2147483647
WiFiClient net;
MQTTClient client(256); // payload increased size from 128 to 256
String myMacAddress;
long nReconnections = 0;
void connect(bool incCounter = true) {
if (incCounter != false) nReconnections++;
Serial.print("Checking wifi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(BROKER_IP);
while (!client.connect(myMacAddress.c_str(), MQTT_USER, MQTT_PASS)) {
Serial.print(".");
delay(5000); // if I got disconnected, because same name at same time, tries to connect 5 seconds after
}
Serial.print("ClientID: ");
Serial.println(myMacAddress.c_str());
//client.setOptions(int keepAlive, bool cleanSession, int timeout);
// The keepAlive option controls the keep alive logInterval in seconds (default: 10).
// The cleanSession option controls the session retention on the broker side (default: true).
// The timeout option controls the default timeout for all commands in milliseconds (default: 1000).
// client.setOptions(180, true, 1300);
// change with logInterval
int keepAlive;
keepAlive = int(1.02 * (logInterval / 1000.));
client.setOptions(keepAlive, true, 3000);
Serial.print("keepAlive time [s]: ");
Serial.println(keepAlive);
client.setWill(sendTopic.c_str(), "Error disconnected sensor ...\"", true, 2);
// void setWill(const char topic[]);
// void setWill(const char topic[], const char payload[]);
// void setWill(const char topic[], const char payload[], bool retained, int qos);
client.subscribe("/hello"); //SUBSCRIBE TO TOPIC /hello
client.subscribe("/temp"); //SUBSCRIBE TO TOPIC /t
client.subscribe("/humidity"); //SUBSCRIBE TO TOPIC /h
client.subscribe("/arduino/setLogIntrvMin");
client.subscribe("/arduino/setLogIntrvMili");
client.subscribe("/arduino/getLogIntrvMili");
client.subscribe("/arduino/getSensorLabel/myPersonalMac");
client.subscribe("/arduino/setSensorLabel/#");
}
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
if (topic == "/arduino/setLogIntrvMin"){
logInterval = payload.toInt() * 1000 * 60;
}
if (topic == "/arduino/setLogIntrvMili"){
logInterval = payload.toInt();
}
if (topic == "/getLogIntrvMili"){
String dataString = "";
dataString = "{\"mac\":\"" + myMacAddress + "\",\"ID\":" + String(sensorId);
dataString += ",\"measurementFrec\":\"" + String(logInterval) + "}";
client.publish(topic, dataString);
}
if (topic == "/setSensorLabel//myPersonalMac"){
// check with IPAddress
// sensorLabel = payload;
}
}
void setup() {
IPAddress ip; // the IP address of my board
//Initialize serial and wait for port to open:
Serial.begin(9600);
// while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
// }
delay(2000);
// attempt to connect to Wifi network:
Serial.print("Attempting to connect to WPA SSID: ");
Serial.print(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(2000);
}
Serial.println(". Connected!");
ip = WiFi.localIP();
Serial.print("localIP: ");
Serial.println(ip);
delay(1000);
// Initializes Enviroment Shield
initializeEnvShield();
// Set MAC Address
myMacAddress = getMacAddress();
// Set sendTopic
sendTopic = "/arduino/";
sendTopic += myMacAddress + "_ID" + String(sensorId);
// pront mac, topic,
Serial.print("MAC: ");
Serial.println(myMacAddress.c_str());
Serial.print("Topic: ");
Serial.println(sendTopic);
Serial.println("Set broker and net.");
client.begin(BROKER_IP, net);
Serial.println("Set on message received.");
client.onMessage(messageReceived);
connect( false ); //false: does not increment nReconnections counter
}
void loop() {
// call loop() regularly to allow the library to send MQTT keep alives which
// avoids being disconnected by the broker; delay(10) in hope to fix disconnection issues https://github.com/256dpi/arduino-mqtt
client.loop();
delay(10);
if (!client.connected()) connect();
// avoid having delays in loop, we'll use the strategy from BlinkWithoutDelay
if (millis() - lastMillis >= logInterval) {
lastMillis = millis();
// reads all different sensor data
readEnvData();
String dataString = "";
dataString = "{\"mac\":\"" + myMacAddress + "\",\"ID\":" + String(sensorId);
dataString += ",\"label\":" + sensorLabel;
dataString += ",\"freeRam\":" + String(freeMemory());
dataString += ",\"nRecon\":" + String(nReconnections);
// dataString += ",\"temp\":" + String(temp, 2);
AddMeasurumentDataToString( dataString );
dataString += "}";
Serial.print("topic: ");
Serial.println(sendTopic);
Serial.print("dataString: ");
Serial.println(dataString);
// see https://github.com/256dpi/arduino-mqtt
// publish(const char topic[], const char payload[], bool retained, int qos);
// client.publish(sendTopic, dataString);
client.publish(sendTopic, dataString, false, 1);
}
}
The code is not finished, and polished
I think, the problems may be:
- memory fragmentation, due to the intense use of String-Objects
- use of Serial.print (I don't know if this affects...)
I run the arduino attached to a standard USB charger.
¿Any advice?