Hola a todos.
Estoy usando mqtt para loggear datos de sensores (temperatura, humedad, ruido, ...). Hasta 18 valores.
Para ello uso mqtt y la librería <MQTT.h> de Joël Gähwiler
Mucha gente usa la librería pubsubclient y he visto que existe esta otra librería llamada ArduinoMqttClient, en la que trabaja también Sandeepmistry. Y bueno, estoy un poco desconcertado por cual es la buena, aunque supongo que las tres son la buena...
Los ejemplos "oficiales" de arduino usan la de Joël Gähwiler, así que también he tirado por ahí. La de ArduinoMqttClient no usa la función loop, sino que usa mqttClient.poll(). Supongo que es lo mismo...
Mi problema, es un poco saber si lo hago bien. Me tiende a desconectarse bastantes veces, y estoy un poco desconcertado.
/*
ArduinoMqttClient - WiFi Simple Sender
Inspired by:
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
This example connects to a MQTT broker and publishes a message to
a topic once a time.
The circuit:
- Arduino MKR 1000, MKR 1010 or Uno WiFi Rev.2 board
*/
// https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoWiFi101/ArduinoWiFi101.ino
#include <MQTT.h>
#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.43" // important: you have to change this to your IP brocker Addres
//#define BROKER_IP "192.168.30.10" // important: you have to change this to your IP brocker Addres
//#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 topic = "/arduino/logData/";
const int sensorId = 4;
String sensorLabel = "holaPlatanete";
long logInterval = 10000; // 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;
void connect() {
Serial.print("Checking wifi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
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.println("\nconnected!");
//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);
client.setOptions((1.05 * logInterval) /1000., true, 3000);
client.setWill(topic.c_str(), "\"Error\":\"disconnected...\"", 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 = "{\"clientMac\":\"" + myMacAddress + "\",\"sensorID\":" + String(sensorId);
dataString += ",\"measurementFrec\":\"" + String(logInterval) + "}";
client.publish(topic, dataString);
}
// "/getSensorLabel//myPersonalMac"
String myString = "/arduino/setSensorLabel/";
myString += myMacAddress;
if (topic == myString){
sensorLabel = payload;
}
if (topic == "/setSensorLabel//myPersonalMac"){
// check with IPAddress
// sensorLabel = payload;
}
}
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
delay(3000);
// while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
// }
// attempt to connect to Wifi network:
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println("You're connected to the network");
Serial.println();
delay(3000);
// Initializes Enviroment Shield
initializeEnvShield();
printMacAddress();
myMacAddress = getMacAddress();
topic += myMacAddress ;
Serial.print("MAC: ");
Serial.println(myMacAddress);
Serial.print("Topic: ");
Serial.println(topic);
Serial.println("Set broker and net.");
client.begin(BROKER_IP, net);
Serial.println("Set on message received.");
client.onMessage(messageReceived);
connect();
}
void loop() {
// call loop() regularly to allow the library to send MQTT keep alives which
// avoids being disconnected by the broker
client.loop();
delay(30);
if (!client.connected()){
Serial.println("Reconnecting inside loop_______________________________________________");
connect();
}
// avoid having delays in loop, we'll use the strategy from BlinkWithoutDelay
if (millis() - lastMillis >= logInterval) {
// reads all different sensor data
readEnvData();
lastMillis = millis();
String dataString = "";
dataString = "{\"clientMac\":\"" + myMacAddress + "\",\"sensorID\":" + String(sensorId);
dataString += ",\"label\":\"" + sensorLabel + "\"";
AddMeasurumentDataToString( dataString );
dataString += "}";
Serial.print("topic: ");
Serial.println(topic);
Serial.print("dataString: ");
Serial.println(dataString);
// see https://github.com/256dpi/arduino-mqtt
// bool publish(const char topic[], const char payload[], bool retained, int qos);
// client.publish(topic, dataString);
// client.publish(topic, dataString, false, 2);
client.publish(topic, dataString);
}
}