Industruino MQTT client over Ethernet

light weight IoT protocol - Industruino example

Tom

MQTT example for Industruino D21G

MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport.

Here we will show a simple example using the Industruino as MQTT client over Ethernet, using this Arduino MQTT library: pubsubclient which is also available from the Arduino IDE library manager. The example sketch below shows the basic functions:

  • connect to the MQTT broker over Ethernet as 'industruinoClient'
  • send a hello message upon connection ('publish' in topic 'industruinoOutTopic')
  • send a regular message with the Industruino 'on_time' (based on millis())
  • receive a message and switch on/off the Industruino's LCD backlight ('subscribe' to topic 'industruinoInTopic')
For the purpose of this blog post, i installed a Mosquitto broker on my Linux laptop (packages mosquitto and mosquitto-clients; i had to also allow traffic on port 1883 via iptables); you don't need this if you're planning to use a public MQTT broker. You can also use this public test server as broker.
Below picture shows the broker log in the upper left window (sudo mosquitto), the publish commands in the upper right, a subscribe client to topic 'industruinoOutTopic' middle bottom (mosquitto_sub -t industruinoOutTopic), and the Arduino IDE Serial Monitor bottom right. 
/*
  Basic MQTT example for Industruino D21G with Ethernet module
  based on the mqtt_basic example of the pubsubclient library

  This sketch demonstrates the basic capabilities of the library.
  It connects to an MQTT server as 'industruinoClient'
  - publishes "hello" to the topic "industruinoOutTopic"
  - publishes on_time to the topic "industruinoOutTopic" every 5 seconds
  - subscribes to the topic "industruinoInTopic", and switches on/off LCD backlight on 1/0

  It will reconnect to the server if the connection is lost using a blocking
  reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
  achieve the same result without blocking the main loop.

*/

#include <SPI.h>
#include <Ethernet2.h>        // Industruino version of Ethernet2
#include <PubSubClient.h>

#include <UC1701.h>
static UC1701 lcd;

// Update these with values suitable for your network.
byte mac[] = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };  // or use Industruino unique MAC
IPAddress ip(192, 168, 1, 199);
IPAddress server(192, 168, 1, 121);

EthernetClient ethClient;
PubSubClient client(ethClient);
unsigned long timestamp;    // for regular publishing

void setup()
{
  SerialUSB.begin(115200);
  pinMode(26, OUTPUT);      // LCD backlight
  digitalWrite(26, HIGH);

  lcd.begin();
  lcd.print("Industruino MQTT demo");
  SerialUSB.println("Industruino MQTT demo");

  client.setServer(server, 1883);
  //  client.setServer("test.mosquitto.org", 1883);   // public test broker
  client.setCallback(callback);

  Ethernet.begin(mac, ip);
  SerialUSB.print("Ethernet started on IP: ");
  SerialUSB.println(Ethernet.localIP());
  lcd.setCursor(0, 1);
  lcd.print("thisIP:");
  lcd.print(Ethernet.localIP());
  lcd.setCursor(0, 2);
  lcd.print("server:");
  lcd.setCursor(0, 3);
  lcd.print(server);
  lcd.print(":1883");
}

void loop() {
  if (millis() - timestamp > 5000) {        // every 5 seconds do this
    if (!client.connected()) {
      reconnect();
    } else {
      String message;
      message = "on_time(ms):";
      message += String(millis());
      SerialUSB.println("SENDING [industruinoOutTopic]: " + message);
      lcd.setCursor(0, 5);
      lcd.print("SENT " + message + "      ");
      int len = message.length() + 1;
      char buf [len];
      message.toCharArray(buf, len);
      client.publish("industruinoOutTopic", buf);     // this function does not take String as parameter
    }
    timestamp = millis();
  }
  client.loop();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    SerialUSB.print("Attempting MQTT connection to server: ");
    SerialUSB.print(server);
    SerialUSB.print(" >>> ");
    lcd.setCursor(0, 5);
    lcd.print("connecting...      ");
    // Attempt to connect
    if (client.connect("industruinoClient")) {
      SerialUSB.println("connected");
      // Once connected, publish an announcement...
      client.publish("industruinoOutTopic", "hello from industruino");
      lcd.setCursor(0, 5);
      lcd.print("SENT hello      ");
      // ... and resubscribe
      client.subscribe("industruinoInTopic");
    } else {
      SerialUSB.print("failed, rc=");
      SerialUSB.print(client.state());
      SerialUSB.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  SerialUSB.print("RECEIVING [");
  SerialUSB.print(topic);
  SerialUSB.print("]: ");
  lcd.setCursor(0, 5);
  lcd.print("RECEIVED ");
  for (int i = 0; i < length; i++) {
    SerialUSB.print((char)payload[i]);
    lcd.print((char)payload[i]);
  }
  lcd.print("              ");
  SerialUSB.println();

  if ((char)payload[0] == '0') {
    digitalWrite(26, LOW);
  }
  if ((char)payload[0] == '1') {
    digitalWrite(26, HIGH);
  }
}