This sketch reads three analog values and sends them twice a second to a mqtt broker. Two implementations are
provided running on Arduino MKR WiFi 1010, one uses the official ArduinoMqttClient
library
and the other one uses Joel's 256dpi MQTT library.
This is using the ArduinoMqttClient
library. It works great with shiftr desktop, but when using it
against a shiftr instance it chokes.
#include <ArduinoMqttClient.h>
#include <WiFiNINA.h>
#include "settings.h"
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const long interval_ms = 500;
unsigned long previousMillis = 0;
int connection_retries = 0;
int count = 0;
unsigned long seq = 0;
void connect() {
if(WiFi.status() == WL_NO_MODULE) {
Serial.println("Wifi is not ready in this board. Situation is hopeless.");
while (true);
}
// try to connecto wifi
Serial.print("Trying to connect to wifi with ssid [ ");
Serial.print(WIFI_SSID);
Serial.println(" ]");
WiFi.disconnect();
while (WiFi.begin(WIFI_SSID, WIFI_PASS) != WL_CONNECTED) {
// failed, retry after waiting for a bit
Serial.print(".");
delay(1500); // in milliseconds
}
Serial.println("I'm connected to the wifi");
Serial.println();
// You can provide a unique client ID, if not set the library uses Arduino-millis()
// Each client must have a unique client ID
// mqttClient.setId("clientId");
// You can provide a username and password for authentication
mqttClient.setUsernamePassword(MQTT_BROKER_USER, MQTT_PASS);
Serial.print("Trying to connect to the MQTT broker: ");
Serial.println(MQTT_BROKER);
if (!mqttClient.connect(MQTT_BROKER, MQTT_PORT)) {
Serial.print(".");
connection_retries++;
delay(2000);
}
}
void setup() {
Serial.begin(9600);
// waiting for serial to start polling
while (!Serial);
Serial.println();
Serial.println("Connected! All ready to go.");
connect();
pinMode(PIN_SENSOR_1, INPUT);
pinMode(PIN_SENSOR_2, INPUT);
pinMode(PIN_SENSOR_3, INPUT);
pinMode(PIN_OUT_1, OUTPUT);
pinMode(PIN_OUT_2, OUTPUT);
pinMode(PIN_OUT_3, OUTPUT);
}
void dispatchPinValue(int which_pin, const char *topic) {
int val = analogRead(which_pin);
if(DEBUG) {
Serial.print("sending message [seq nr. ");
Serial.print(seq);
Serial.println("]");
}
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic);
mqttClient.print("value ");
mqttClient.print(val);
mqttClient.endMessage();
mqttClient.flush();
seq++;
}
void loop() {
mqttClient.poll(); // we need to do this to avoid being disconnected from the broker
delay(10);
if (!mqttClient.connected()) {
connect();
}
dispatchPinValue( PIN_SENSOR_1, "lightsensor1" );
dispatchPinValue( PIN_SENSOR_2, "lightsensor2" );
dispatchPinValue( PIN_SENSOR_3, "lightsensor3" );
delay(interval_ms);
}
This second implementation uses the 256dpi library, and I haven't managed to get it to connect to either, shiftr desktop or a shiftr cloud instance. I am not entirely sure how this client should authenticate.
#include <MQTT.h>
#include <WiFiNINA.h>
// installed mqqt library from https://github.com/256dpi/arduino-mqtt
#include "settings.h"
WiFiClient net;
MQTTClient client(net);
const long interval_ms = 500;
unsigned long lastMillis = 0;
int connection_retries = 0;
int count = 0;
void connect() {
if(WiFi.status() == WL_NO_MODULE) {
Serial.println("wifi is not ready in this board. Situation is hopeless.");
while (true);
}
// try to connec to wifi
Serial.print("trying to connect to wifi with ssid [ ");
Serial.print(WIFI_SSID);
Serial.println(" ]");
WiFi.disconnect();
while (WiFi.begin(WIFI_SSID, WIFI_PASS) != WL_CONNECTED) {
// failed, retry after waiting for a bit
Serial.print(".");
delay(500); // in milliseconds
}
Serial.println("i'm connected to wifi now. looking good.");
Serial.println();
Serial.print("connecting to mqtt broker ");
Serial.print(MQTT_BROKER);
// @NOTE tried with broker username and broker password and without (using shiftr desktop) no success
while (!client.connect(MQTT_DEVICE_ID)) { //, MQTT_BROKER_USER, MQTT_BROKER_PASS)) {
Serial.print(".");
delay(1000);
}
Serial.println("\nall systems are go!");
}
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
// Note: Do not use the client in the callback to publish, subscribe or
// unsubscribe as it may cause deadlocks when other things arrive while
// sending and receiving acknowledgments. Instead, change a global variable,
// or push to a queue and handle it in the loop after calling `client.loop()`.
}
void setup() {
Serial.begin(9600);
// waiting for serial to start polling
while (!Serial) ;
client.begin(MQTT_BROKER, MQTT_PORT, net);
client.onMessage(messageReceived);
connect();
pinMode(PIN_SENSOR_1, INPUT);
pinMode(PIN_SENSOR_2, INPUT);
pinMode(PIN_SENSOR_3, INPUT);
pinMode(PIN_OUT_1, OUTPUT);
pinMode(PIN_OUT_2, OUTPUT);
pinMode(PIN_OUT_3, OUTPUT);
}
void dispatchPinValue(int which_pin, const char *topic) {
int val = analogRead(which_pin);
if(DEBUG) {
Serial.println("sending message");
}
client.publish(topic, String(val) );
}
void loop() {
client.loop(); // we need to do this to avoid being disconnected from the broker
delay(10);
if (!client.connected()) {
connect();
}
// publish a message roughly every second.
if (millis() - lastMillis > interval_ms) {
lastMillis = millis();
dispatchPinValue( PIN_SENSOR_1, "lightsensor1" );
dispatchPinValue( PIN_SENSOR_2, "lightsensor2" );
dispatchPinValue( PIN_SENSOR_3, "lightsensor3" );
}
}