Skip to content

Instantly share code, notes, and snippets.

@m2mIO-gister
Last active January 6, 2018 00:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m2mIO-gister/4288732 to your computer and use it in GitHub Desktop.
Save m2mIO-gister/4288732 to your computer and use it in GitHub Desktop.
Arduino Client for the m2m.io platform. Handles provisioning an Arduino device to a user's account as well as publishing sensor values to the cloud platform.
#include <SPI.h>
#include <PubSubClient.h>
#include <Ethernet.h>
/*
* m2m.io Client App
*
* Client application for m2m.io M2M platform.
*
* Client handles provioning as well as provides a template
* for publishing sensor data to the platform.
*/
#define M2MIO_USERNAME "<insert m2m.io username here>"
#define M2MIO_PASSWORD "<insert md5 hash of m2m.io password here>"
#define M2MIO_DOMAIN "<insert domain from m2m.io here - can be found on account tab>"
#define M2MIO_DEVICE_ID "<insert desired device id here - should be unique from your other devices>"
#define MQTT_SERVER "q.m2m.io"
byte MAC_ADDRESS[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x31, 0xB8 };
EthernetClient ethernetClient;
PubSubClient sensorClient(MQTT_SERVER, 1883, sensorCallback, ethernetClient);
PubSubClient provisionClient(MQTT_SERVER, 1883, provisionCallback, ethernetClient);;
char clientID[50];
char topic[50];
char msg[50];
// jumper pin
// (tie to ground to provision device on startup)
// (leave floating for normal sensor mode)
int jPin = 0;
// potentiometer sensor pin
int potPin = 5;
// variables to store current time (millis)
// used to control frequency of sensor reporting
unsigned long now = 0;
unsigned long sentTime = 0;
#define REPORTING_INTERVAL_MS 1000
// flag to keep track of provisioning message sent (only send one)
boolean provisionMsgSent = false;
// device mode
// true = provisioning device to user on platform
// upon bootup or reset device sends registration
// message to m2m.io platform
// false = normal, sensor reporting mode
// device connects to platform and sends a sensor
// value to the platform at a configurable interval
boolean provisioningMode = 0;
void setup()
{
// init serial link for debugging
Serial.begin(9600);
// setup potentiometer pin
pinMode(potPin, INPUT);
// read jumper to determine mode (provisioning / normal)
pinMode(jPin, INPUT);
delay(2000);
//Serial.println(analogRead(jPin));
if (analogRead(jPin) < 50) {
Serial.println("Entering Provisioning Mode");
provisioningMode = true;
} else {
Serial.println("Entering Sensor Mode");
provisioningMode = false;
}
// initialize ethernet library
if (Ethernet.begin(MAC_ADDRESS) == 0)
{
Serial.println("Failed to configure Ethernet using DHCP");
return;
}
if (provisioningMode) {
// Device is in provisioning mode:
// 1. create MQTT client for provisioning
// 2. configure enrollment message and topic
// 3. (message is sent later in loop())
String clientIDStr = M2MIO_DEVICE_ID;
clientIDStr.toCharArray(clientID, clientIDStr.length()+1);
provisionClient.connect(clientID);
Serial.println(clientIDStr);
String topicStr = "public/enroll/";
topicStr.concat(M2MIO_USERNAME);
topicStr.toCharArray(topic, topicStr.length()+1);
Serial.println(topicStr);
String enrollMsg = "{\"type\":\"Arduino\",\"mac\":\"";
enrollMsg.concat(M2MIO_DEVICE_ID);
enrollMsg.concat("\"}");
enrollMsg.toCharArray(msg, enrollMsg.length()+1);
Serial.println(enrollMsg);
} else {
// Device is in sensor mode:
// 1. create MQTT client for publishing sensor data
// 2. configure sensor topic
// 3. (messages are sent later in loop())
String clientIDStr = "Arduino/";
clientIDStr.concat(M2MIO_DEVICE_ID);
clientIDStr.toCharArray(clientID, clientIDStr.length()+1);
String topicStr = M2MIO_DOMAIN;
topicStr.concat("/Arduino/");
topicStr.concat(M2MIO_DEVICE_ID);
topicStr.toCharArray(topic, topicStr.length()+1);
}
}
void loop()
{
now = millis();
if (!provisioningMode) {
// sensor mode
// 1. If not connected to MQTT broker --> connect
// 2. If time to publish:
// - get sensor reading
// - build payload with sensor value
// - publish to m2m.io platform
if (!sensorClient.connected()) {
sensorClient.connect(clientID, M2MIO_USERNAME, M2MIO_PASSWORD);
}
// loop runs more frequently than we'd want to pubish
// only publish every "reporting interval" milliseconds
if ((now - sentTime) > REPORTING_INTERVAL_MS) {
sentTime = now;
// get sensor value
int levelReading = analogRead(potPin);
// build MQTT message payload
// m2m.io messages need to be JSON encoded for
// data to be stored in the platform for later recall
String dataMsg = "{\"t\":";
dataMsg.concat(levelReading);
dataMsg.concat("}");
dataMsg.toCharArray(msg, dataMsg.length()+1);
sensorClient.publish(topic, msg);
}
sensorClient.loop();
} else {
// provisioning mode
// 1. If not connected to MQTT broker --> connect
// 2. Publish provisioning message
if (!provisionClient.connected()) {
provisionClient.connect(clientID, M2MIO_USERNAME, M2MIO_PASSWORD);
}
// send the provisioning message (only once)
if (!provisionMsgSent) {
Serial.println("Sending provisioning message.");
provisionClient.publish(topic, msg);
provisionMsgSent = true;
}
provisionClient.loop();
}
}
// handles message arrived on subscribed topic(s)
// in this application we do not subscribe so this is a dummy method
void sensorCallback(char* topic, byte* payload, unsigned int length) { }
// handles message arrived on subscribed topic(s)
// in this application we do not subscribe so this is a dummy method
void provisionCallback(char* topic, byte* payload, unsigned int length) { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment