IoT boilerplate

From MDD wiki
Jump to navigation Jump to search

About

This page will not explain how IoT works, but will give you examples on getting started. In the resource section of this page you will find more step-by-step tutorials


In order to setup a device to use the HvA IoT network have a look at Iot network

MDD-tardis IoT broker

The MDD has a server that is configured to be used for IoT applications.

Connection details
server mqtt.mdd-tardis.net or 37.97.203.138
port 1883 or 9001 (when using websockets)
user mdduser
pass IoTMDD


When using platforms like Arduino or processing use port number 1883.

⚠️ In javascript use port number 9001.

Tools

There are some free tools out there that help you set up the connection to the MQTT broker

Resources to get MQTT client code
Arduino https://github.com/256dpi/arduino-mqtt
Processing https://github.com/256dpi/processing-mqtt
JavaScript https://github.com/mqttjs/MQTT.js
Python (raspberry pi) http://www.eclipse.org/paho/clients/python
C# (unity) https://www.eclipse.org/paho/index.php?page=clients/dotnet/index.php


Get started code

Python

Using paho-mqtt to connect to our MQTT broker

import paho.mqtt.client as mqtt
import time

host="37.97.203.138"
user="mdduser"
pwd="IoTMDD"
clientID="LearningStudent"
topic="/testtopic"

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    code = str(rc)
    print(f'connected with result code {code}')

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    print(f'Subscribing to {topic}')
    client.subscribe(topic)

def on_disconnect(client, userdata, rc):
    code = str(rc)
    print(f'disconnected with result code {code}')

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    message = str(msg.payload)
    print(f'Message received from topic: {msg.topic}: {message}')

client = mqtt.Client(clientID)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message

print(f'connecting to {host} as {clientID}')
client.username_pw_set(user, pwd)
client.will_set(topic)
client.connect(host)


print(f'start loop')
client.loop_start()

while True:
    client.publish(topic, "test")
    time.sleep(1)

Javascript

When using javascript to connect to our MQTT broker, use port 9001 and a library like the Paho MQTT client

<html>

   <head>
   	<!-- load the paho library -->
   	<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.2/mqttws31.min.js" type="text/javascript"/>
   	<script type="text/javascript">
   		var host = "37.97.203.138";
   		var port = 9001;
   		var user = "mdduser";
   		var pass = "IoTMDD";
   		var clientID = "LearningStudent"
   		var topic = "/testtopic"
   		var client;

   		function init() {
   			println("Connecting to "+host+" as "+clientID);

   			client = new Paho.MQTT.Client(host, Number(port), clientID);
		    // Set callback handlers
		    client.onConnectionLost = onConnectionLost;
		    client.onMessageArrived = onMessageArrived;
		    // Connect the client, if successful, call onConnect function
		    client.connect({
                      userName: user,
                      password: pass,
                      onSuccess: onConnect,
                      useSSL: window.location.protocol === "https:",
                      onFailure: console.log,
		    });
   		}

   		// Called when the client connects
		function onConnect() {
		    println('connected.');
		    println('Subscribing to: ' + topic);

		    // Subscribe to the requested topic
		    client.subscribe(topic);

		    document.getElementById('sendButton').disabled = false;
		}

		function sendMessage() {
			client.send(topic, "Hello world!");
		}

   		function onConnectionLost(responseObject) {
		    println('Connection lost');
		    if (responseObject.errorCode !== 0) {
		        println('ERROR: ' + + responseObject.errorMessage);
		    }
		}

		// Called when a message arrives
		function onMessageArrived(message) {
		    console.log("onMessageArrived: " + message.payloadString);
		    println('Message received from topic: ' + message.destinationName + ': ' + message.payloadString);
		}

   		function println(msg) {
   			document.getElementById('messages').innerHTML+='<span>'+msg+'</span><br/>';
   		}

   	</script>
   </head>

   <body>
     <h1>Simple Paho MQTT demo</h1>
     <input type="button" id="connectButton" onclick="init();" value="connect" enabled/>
     <input type="button" id="sendButton" onclick="sendMessage();" value="send a message" disabled/>
     <p/>
     <div id="messages"></div>
   </body>

</html>

Processing

This processing example shows how to send and receive data on two different channels by subscribing and publishing to different channels

import mqtt.*;

MQTTClient client;
String lastMessageKeyboard="";
String lastMessageMouse="";

void setup() {
  size(500, 200);
  // create MQTT Client, connect to our server and subscribe to two channels
  client = new MQTTClient(this);
  client.connect("mqtt://mdduser:IoTMDD@37.97.203.138:1883", "MDDStudent");
  client.subscribe("/testchannel/keyboard");
  client.subscribe("/testchannel/mouse");
}

void keyPressed() {
  client.publish("/testchannel/keyboard", ""+key);
}

void draw() {
  background(255);
  fill(0);
  text("type keyboard to send messages",10,20);
  text("Last received message on channel /testchannel/keyboard: "+lastMessageKeyboard,10,40);
  text("Move and click mouse to send messages",10,100);
  text("Last received message on channel /testchannel/mouse: "+lastMessageMouse,10,120);
}

void mousePressed() {
 client.publish("/testchannel/mouse", "mousePressed "+mouseX+" "+mouseY);
}
void mouseMoved() {
 client.publish("/testchannel/mouse", "mouseMoved "+mouseX+" "+mouseY);
}
void mouseDragged() {
 client.publish("/testchannel/mouse", "mouseDragged "+mouseX+" "+mouseY);
}
void mouseReleased() {
 client.publish("/testchannel/mouse", "mouseReleased "+mouseX+" "+mouseY);
}

void messageReceived(String topic, byte[] payload) {
  String message = new String(payload);
  println("new message: " + topic + " - " + message);
  
  if (topic.equals("/testchannel/keyboard")) {
    lastMessageKeyboard = message;
  }
  
  if (topic.equals("/testchannel/mouse")) {
    lastMessageMouse = message;
  }
}

P5js

More P5js examples can be found at this github repository

<html>
  <head>
    <!-- Load P5js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
    <!-- Load Paho MQTT -->
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js"
      type="text/javascript"
    ></script>
    <script>
      /*
    p5.js MQTT Client example
    This example uses p5.js: https://p5js.org/
    and the Eclipse Paho MQTT client library: https://www.eclipse.org/paho/clients/js/
    to create an MQTT client that sends and receives MQTT messages.
    The client is set up for use on the shiftr.io test MQTT broker (https://next.shiftr.io/try),
    but has also been tested on https://test.mosquitto.org

    created 12 June 2020
    modified 20 Aug 2020
    by Tom Igoe
*/

      // MQTT client details:
      let broker = {
        hostname: "public.cloud.shiftr.io",
        port: 443,
      };
      // MQTT client:
      let client;
      // client credentials:
      let creds = {
        clientID: "p5Client",
        userName: "public",
        password: "public",
      };
      // topic to subscribe to when you connect:
      let topic = "notes";

      // a pushbutton to send messages
      let sendButton;
      let localDiv;
      let remoteDiv;

      // intensity of the circle in the middle
      let intensity = 255;

      function setup() {
        createCanvas(400, 400);
        // Create an MQTT client:
        client = new Paho.MQTT.Client(
          broker.hostname,
          Number(broker.port),
          creds.clientID
        );
        // set callback handlers for the client:
        client.onConnectionLost = onConnectionLost;
        client.onMessageArrived = onMessageArrived;
        // connect to the MQTT broker:
        client.connect({
          onSuccess: onConnect, // callback function for when you connect
          userName: creds.userName, // username
          password: creds.password, // password
          useSSL: true, // use SSL
        });
        // create the send button:
        sendButton = createButton("send a message");
        sendButton.position(20, 20);
        sendButton.mousePressed(sendMqttMessage);
        // create a div for local messages:
        localDiv = createDiv("local messages will go here");
        localDiv.position(20, 50);
        localDiv.style("color", "#fff");
        // create a div for the response:
        remoteDiv = createDiv("waiting for messages");
        remoteDiv.position(20, 80);
        remoteDiv.style("color", "#fff");
      }

      function draw() {
        background(50);
        // draw a circle whose brightness changes when a message is received:
        fill(intensity);
        circle(width / 2, height / 2, width / 2);
        // subtract one from the brightness of the circle:
        if (intensity > 0) {
          intensity--;
        }
      }

      // called when the client connects
      function onConnect() {
        localDiv.html("client is connected");
        client.subscribe(topic);
      }

      // called when the client loses its connection
      function onConnectionLost(response) {
        if (response.errorCode !== 0) {
          localDiv.html("onConnectionLost:" + response.errorMessage);
        }
      }

      // called when a message arrives
      function onMessageArrived(message) {
        remoteDiv.html("I got a message:" + message.payloadString);
        let incomingNumber = parseInt(message.payloadString);
        if (incomingNumber > 0) {
          intensity = 255;
        }
      }

      // called when you want to send a message:
      function sendMqttMessage() {
        // if the client is connected to the MQTT broker:
        if (client.isConnected()) {
          // make a string with a random number form 0 to 15:
          let msg = String(round(random(15)));
          // start an MQTT message:
          message = new Paho.MQTT.Message(msg);
          // choose the destination topic:
          message.destinationName = topic;
          // send it:
          client.send(message);
          // print what you sent:
          localDiv.html("I sent: " + message.payloadString);
        }
      }
    </script>
  </head>

  <body></body>
</html>

Arduino

Arduino Yun

This code uses an Arduino Yún and the MQTT library.

// This example uses an Arduino Yun or a Yun-Shield

#include <Bridge.h>
#include <BridgeSSLClient.h>
#include <MQTT.h>

#define broker "37.97.203.138"
#define port 1883
#define user "mdduser"
#define pass "IoTMDD"
#define userID "StudentOnArduino"

BridgeClient net;
MQTTClient client;

unsigned long lastMillis = 0;

void setup() {
  Bridge.begin();
  Serial.begin(115200);

  // MQTT brokers usually use port 8883 for secure connections.
  client.begin(broker, port, net);
  client.onMessage(messageReceived);

  connect();
}

void connect() {
  Serial.print("connecting as ");
  Serial.print(userID);
  Serial.print(" to ");
  Serial.println(broker);
  while (!client.connect(userID, user, pass)) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("\nconnected!");
  client.subscribe("/testarduino");
  // client.unsubscribe("/hello");
}

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
}

void loop() {
  client.loop();

  if (!client.connected()) {
    connect();
  }

  // publish a message roughly every second.
  if (millis() - lastMillis > 1000) {
    lastMillis = millis();
    Serial.println("Sending message to broker...");
    client.publish("/testarduino", "hello from Arduino");
  }

}

Arduino ESP32 / ESP8266

This code uses a board that has an ESP32 or ESP8266 chip (like the adafruit feather ESP32)

Checkout Getting started with arduino to setup a connected device

 // This example uses an Adafruit arduino feather
 #ifdef ESP32
 #include <WiFi.h>
 #else
 #include <ESP8266WiFi.h>
 #endif
 
 #include <PubSubClient.h>
 
 WiFiClient espClient;
 PubSubClient client(espClient);
 
 // Wifi
 const char *ssid = "iotroam";
 const char *password = "loislane";
 
 // MQTT
 const char *mqtt_server = "37.97.203.138";
 const int mqtt_port = 1883;
 const char *mqtt_user = "mdd";
 const char *mqtt_password = "loislane";
 const String mqtt_identifier = "battle-bot";
 
 // Data
 unsigned long lastMillis = 0;
 
 void setup() {
   Serial.begin(9600);
 
   setup_wifi();
   
   // Connect to the MQTT client
   client.setServer(mqtt_server, mqtt_port);
   // Receive data from the MQTT
   client.setCallback(callback);
 }
 
 void loop() {
   if (!client.connected())
   {
       digitalWrite(LED_BUILTIN, LOW);
       reconnect();
   }
   
   client.loop();
     
   // Publish a message roughly every second.
   if (millis() - lastMillis > 1000) {
     lastMillis = millis();
     Serial.println("Sending message to broker...");
     client.publish("/testarduino/send", "hello from Arduino");
   }
 }
 
 void setup_wifi()
 {
     Serial.print("Board MAC Address:  ");
     Serial.println(WiFi.macAddress());
 
     delay(10);
     Serial.println();
     Serial.print("Connecting to ");
     Serial.print(ssid);
     
     // We start by connecting to a WiFi network
     WiFi.begin(ssid, password);
 
     // Wait untill the WiFi status is WL_CONNECTED (active internet connection)
     while (WiFi.status() != WL_CONNECTED)
     {
         delay(500);
         Serial.print(".");
     }
 
     Serial.println("");
     Serial.println("");
     Serial.println("WiFi connected");
     Serial.print("IP address: ");
     Serial.println(WiFi.localIP());
     Serial.println("");
     Serial.println("");
 }
 
 void reconnect()
 {
     // Loop until we're reconnected again
     while (!client.connected())
     {
         // Create a unique identifier for this arduino
         char identifier[50];
         String unique_name = mqtt_identifier + "-" + String(random(0xffff), HEX);
         String(unique_name).toCharArray(identifier, String(mqtt_identifier).length() + 1);
         
         Serial.print("Connecting to MQTT...");
 
         // Trying to make a connection
         if (client.connect(identifier, mqtt_user, mqtt_password))
         {
             Serial.println("");
             Serial.println("");
             Serial.println("MQTT Connected");
             Serial.print("Identifier: ");
             Serial.println(identifier);
             Serial.println("");
             Serial.println("");
             digitalWrite(LED_BUILTIN, HIGH);
 
             // Subscribe to a topic
             client.subscribe("/testarduino/receive");
         }
         else
         {
             Serial.print("failed, rc=");
             Serial.print(client.state());
             Serial.println(" try again in 5 seconds");
             // Wait 5 seconds before retrying
             delay(5000);
         }
     }
 }
 
 void callback(char *topic, byte *message, unsigned int length)
 {
     Serial.print("Received message on topic: ");
     Serial.print(topic);
     Serial.print(". Message: ");
     String messageTemp;
 
     for (int i = 0; i < length; i++)
     {
         Serial.print((char)message[i]);
         messageTemp += (char)message[i];
     }
     
     Serial.println();
 }

Unity

Follow this tutorial


ZigSim

See Smartphone as a lab full of sensors

Convert MQTT ZigSim messages to be used in your code

Usage ZigSim message = ZigSim.CreateFromJSON(mqttMessage);

// ZigSim.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Gyro {
    public float x;
    public float y;
    public float z;
}

[System.Serializable]
public class Quaternion {
    public float x;
    public float y;
    public float z;
    public float w;
}

[System.Serializable]
public class Accelerometer {
    public float x;
    public float y;
    public float z;
}

[System.Serializable]
public class ZigSim
{
    public Gyro gyro;
    public Quaternion quaternion;
    public Accelerometer accel;

    public static ZigSim CreateFromJSON(string jsonString)
    {
        return JsonUtility.FromJson<ZigSim>(jsonString);
    }
}

Other resources

  • Adafruit has a great step-by-step tutorial for getting started with IoT.
  • Shiftr also hosts an easy-to-learn platform for getting started with IoT.
  • More examples can be found over here.