@madpilot makes

Garage Door Opener – Let’s connect

So, now we have an MQTT server, lets see if we can get the ESP8266 to connect to it.

I’m going to use Nick O’Leary’s pubsubclient library. It’s pretty easy to install – find Manage Libraries in the Sketch Menu, search for pubsubclient and it should appear. Hit install.

After we physically connected to the WIFI (Which we’ll do via via hard coding the SSID and passkey for the moment – we’ll do that properly later), there are two things we need to do:

  1. Connect to the MQTT server – no security for the moment, we’ll work up to that
  2. Subscribe to a message. We provide the library with a callback function that gets called every time the server receives a message topic that we are subscribed to.

Here is the some proof of concept code that does all of that:

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <PubSubClient.h>

#define SSID "your-wifi-ssid"
#define PASSKEY "your-wifi-password"
#define MQTT_IP "ip-address-of-the-mqtt-server"
#define MQTT_PORT 1883
#define MQTT_NAME "garage"

#define TOPIC "test"

#define QOS_LEVEL 0

// PubSub client
WiFiClient espClient;
PubSubClient pubSubClient(espClient);
void PubSubCallback(char* topic, byte* payload, unsigned int length);
long lastPubSubConnectionAttempt = 0;

void PubSubSetup() {
  pubSubClient.setServer(MQTT_IP, MQTT_PORT);
  pubSubClient.setCallback(PubSubCallback);
}

boolean PubSubConnect() {
  Serial.print("Connecting to MQTT server...");

  if(!pubSubClient.connect(MQTT_NAME)) {
    Serial.println("\nCouldn't connect to MQTT server. Will try again in 5 seconds.");
    return false;
  }

  if(!pubSubClient.subscribe(TOPIC, QOS_LEVEL)) {
    Serial.print("\nUnable to subscribe to ");
    Serial.println(TOPIC);
    pubSubClient.disconnect();
    return false;
  }

  Serial.println(" Connected.");
  return true;
}

void PubSubLoop() {
  if(!pubSubClient.connected()) {
    long now = millis();

    if(now - lastPubSubConnectionAttempt > 5000) {
      lastPubSubConnectionAttempt = now;
      if(PubSubConnect()) {
        lastPubSubConnectionAttempt = 0;
      }
    }
  } else {
    pubSubClient.loop();
  }
}

void PubSubCallback(char* topic, byte* payload, unsigned int length) {
  char *p = (char *)malloc((length + 1) * sizeof(char *));
  strncpy(p, (char *)payload, length);
  p[length] = '\0';

  Serial.print("Message received: ");
  Serial.print(topic);
  Serial.print(" - ");
  Serial.println(p);

  free(p);
}

void connectWifi(const char* ssid, const char* password) {
  int WiFiCounter = 0;
  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED && WiFiCounter < 30) {
    delay(1000);
    WiFiCounter++;
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void setup() {
  Serial.begin(115200);
  connectWifi(SSID, PASSKEY);
  PubSubSetup();
}

void loop() {
  PubSubLoop();
}

To run this, first fire up our MQTT server using docker-compose up, next load up the above code on the ESP8266, replacing the constants at the top of the file with the relevant settings.

If you are running Docker on Linux, or using Docker for Mac; or Docker for Windows the IP address of the server will be the same as the IP address of your computer.

If you are running docker-machine, you will need to run docker-machine ip to find out the local IP address.

Open up the serial monitor and you should see something like this:

Connecting to [what ever your ssid is].
WiFi connected
IP address: [some IP address]
Connecting to MQTT server... Connected.

Now, if we publish a message on to the queue

docker-compose run mosquitto-publisher -t "test" -m "Hello Arduino!"

We should see the Arduino consuming the message:

Message received: test - Hello Arduino!

If you don’t see the message, there should be hints in the serial monitor about what went wrong.

Things to look out for:

  • If you can’t connect to the WiFI, check your SSID and passkey
  • If you can’t connect to the MQTT server, check your IP address. Also, check the docker output – you should see a message when the Arduino connects.

2 comments

  1. command_topic isnt defined before
  2. It's a typo, it should be TOPIC. I've fixed the post now

Leave a comment