Skip to content

Instantly share code, notes, and snippets.

@dropmeaword
Created January 20, 2021 10:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dropmeaword/2c651d84fa8d4a1d66483741f71cc82c to your computer and use it in GitHub Desktop.
Save dropmeaword/2c651d84fa8d4a1d66483741f71cc82c to your computer and use it in GitHub Desktop.
description of problems I am having with shiftr.io

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" );
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment