Arduino Mqtt Client

In this topic I will be sending data from a small device using a highly volatile protocol to any other client that might be interested in this data. This concept is also called pub/sub or the publish subsrcibe pattern. We need a few components to make this possible:

  • The small device with client software (for publishing)
  • A messaging protocol (used by the client software to either publish or subscribe)
  • A broker (for managing the pub/sub data flows). For more information goto this topic

The small device

Arduino can sense the environment by receiving input from a variety of sensors and can affect its surroundings by controlling lights, motors, and other actuators. The microcontroller on the board is programmed using the Arduino programming language (based on Wiring) and the Arduino development environment (based on Processing). Arduino projects can be stand-alone or they can communicate with software running on a computer (e.g. Flash, Processing, MaxMSP). For more information: http://www.arduino.cc/. For this topic I will use two Arduino components: the Arduino Uno Rev 3 and a WiFi shield.

The protocol

MQTT is a machine-to-machine (M2M)/”Internet of Things” connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium. For more information: http://mqtt.org/.

What is happening?

Box closed Box open

The focus of this topic will be on the Arduino Uno client. As shown in the pictures, there a three buttons attached to the Uno. The wiring schema looks like this:

Schema

The wiring schema is not complete: the WiFi shield is missing but from a wiring point of view this does not matter much (the resistors used are all 10k). There are a few issues related to the WiFi shield:

  • Due to communication between the Uno and the WiFi shield, the digital input 4 can not be used
    Arduino WiFi Shield
  • These instructions

When all this was done, the Arduino Mqtt client had to be created. First of all an Arduino library has to be found. The one I used is: Knolleary. Before being able to use this, again an issue:

  • Socket read error: I added both cpp and h file to my Arduino sketch. Next I changed the code of the cpp file as described with the link (so add the two lines with
    d[0] = 0;
    d[1] = 6;

And finally we have some code:

#include
#include
#include "PubSubClient.h"

// Update these with values suitable for your network.
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte server[] = { 10, 0, 1, 3 };
char ssid[] = "******"; // your network SSID (name)
char pass[] = "******"; // your network password
char topic[] = "hello/world";
int status = WL_IDLE_STATUS; // the Wifi radio's status

void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}

WiFiClient wfClient;
PubSubClient client(server, 1883, callback, wfClient);

// set pin numbers:
const int buttonPin2 = 2; // the number of the pushbutton pin
const int buttonPin3 = 3; // the number of the pushbutton pin
const int buttonPin5 = 5; // the number of the pushbutton pin

// variables will change:
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState5 = 0;

void setup()
{
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin5, INPUT);
  Serial.begin(9600);

  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while(true);
  }

  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }

  Serial.println("You're connected to the network");
  printWifiData();
  printCurrentNet();
}

void loop()
{
  if (!client.connected()) {
    delay(1000);
    Serial.println("Connecting to Mosquitto");
    if (client.connect("ArduinoClient")) {
      client.publish(topic,"Connected to Mosquitto");
      Serial.println("Connected to Mosquitto");
    }
  } else {
    // read the state of the pushbutton value:
    buttonState2 = digitalRead(buttonPin2);
    buttonState3 = digitalRead(buttonPin3);
    buttonState5 = digitalRead(buttonPin5);

    if (buttonState2 == HIGH) {
      Serial.println("Button 2 pressed");
      client.publish(topic,"RED");
    }

    if (buttonState3 == HIGH) {
      Serial.println("Button 3 pressed");
      client.publish(topic,"GREEN");
    }

    if (buttonState5 == HIGH) {
      Serial.println("Button 5 pressed");
      client.publish(topic,"BLACK");
    }
  }
  client.loop();
}

void printWifiData() {
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.println(mac[0],HEX);
}

void printCurrentNet() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  Serial.print(bssid[5],HEX);
  Serial.print(":");
  Serial.print(bssid[4],HEX);
  Serial.print(":");
  Serial.print(bssid[3],HEX);
  Serial.print(":");
  Serial.print(bssid[2],HEX);
  Serial.print(":");
  Serial.print(bssid[1],HEX);
  Serial.print(":");
  Serial.println(bssid[0],HEX);
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption,HEX);
}

Basically this code will connect to the WiFi netwerk ssid with password pass. When an ip address is obtained, it will connect to the Mqtt broker with ip address server. There is no security setup but this is an option. When connected to the broker, the code will start looping:

  • Each time a button is pushed, Mqtt messages are sent to the broker
  • with client.loop() the connection with the broker will be kept alive when nothing is sent to the broker
  • The topic used is “hello/world” so when a subscriber is using this topic as well, the data can be received

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s