---
# System prepended metadata

title: Mosquitto MQTT
tags: [MQTT, ESP32]

---

---
title: 'Mosquitto MQTT'
disqus: hackmd
---

Mosquitto MQTT
===
###### tags: `ESP32` `MQTT` 
## Table of Contents

[TOC]

## MQTT Broker Install

If you are a total beginner to this, start here!

1. Visit [mosquitto.org](https://mosquitto.org/download/)
2. Download "mosquitto-2.0.14-install-windows-x64.exe"
![](https://i.imgur.com/SeXzwYb.png)

3. Install
![](https://i.imgur.com/axJ28Pl.png)

4. Stop Service
![](https://i.imgur.com/pKe86yF.png)

5. 設定防火牆 1883 Port 
![](https://i.imgur.com/hiqU9m3.png)

6. 設定 mosquitto.conf
![](https://i.imgur.com/Gl1SA9I.png)
7. 在最下方加上 `allow_anonymous true`
8. 重啟 Service


Test MQTT
---

1. Chrome 下載 MQTTLens
![](https://i.imgur.com/Ku9QhEW.png)

2. 設定 Hostname
![](https://i.imgur.com/pll7HDY.png)


Arduino MQTT
---

```arduino=1
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID"; //更改為您的 WiFi 帳號
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; //更改為您的 WiFi 密碼 
const char* mqtt_server = "192.168.50.45";
const char* pub_topic = "SYSID_001";
const char* sub_topic = "SYSID_002";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE	(50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  // =================================================
  // Message arrived [SYSID_002] value
  // =================================================
  
  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    //digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    //digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      //=======================================================================
      // Once connected, publish an announcement...
      client.publish(pub_topic, "ESP8266 connected");
      // ... and resubscribe
      //client.subscribe("inTopic");      
      client.subscribe(sub_topic);
      //=======================================================================      
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  //pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish(pub_topic, msg);
  }
  
  // =================================================
  // Publish message: hello world #70
  // =================================================
  
  delay(100);
}
```

參考
--- 
:::info
* [MQTT教學（四）：使用MQTTLens訂閱與發布MQTT訊息](https://swf.com.tw/?p=1009)
* [MQTT教學（六）：使用PubSubClient程式庫開發Arduino MQTT應用](https://swf.com.tw/?p=1021)
:::

## ESP32 BLE + MQTT
### MQTT-BLE
An ESP32-arduino file for using the ESP32 as a listener for bluetooth devices. Set your device MAC-addresses in the code, and your topic/payload for the mqtt, and the ESP32 will send MQTT-messages as long as it sees the given devices.

If you need more devices just add more addresses, and if you need more people, just copy/paste the if-statements in the loop()-function at the bottom of the code.

### To transfer this code to your ESP32:
Go to File -> Preferences -> Additional Boards Manager URLs and add the following link: https://dl.espressif.com/dl/package_esp32_index.json

* ****Go to Tools -> Board -> Boards Manager and search for ESP32. Choose install.****

* ****When the Install is finished restart Arduino and select Tools -> Board -> ESP32 Dev****

* ****Change Partition Scheme to No OTA(Large App)****

Verify and Upload the code and you should be good to go.

The code will output debug-messages to Serial 115200, so it's probably a good idea to monitor this the first time you run it.
```arduino=1
#include "WiFi.h"
#include <PubSubClient.h>

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

// WIFI
const char* ssid = "YOUR_SSID";
const char* password  = "YOUR_WIFI_PASSWORD";
WiFiClient espClient;

// MQTT
const char* mqtt_server = "MQTT_SERVER_IP";
int port = 1883; //YOUR PORT - Standard for MQTT is 1883
const char* topic = "BLEStatus"; // YOUR TOPIC
const char* person1payload = "Jack/state"; // Set your payloads here
const char* person2payload = "Jill/state";
PubSubClient client(espClient);

//Bluetooth
int BTScanTime = 5;
BLEScan* pBLEScan;
BLEAddress tag1 = BLEAddress("ff:ff:ff:ff:ff:ff"); //Your address here
BLEAddress tag2 = BLEAddress("ff:ff:ff:ff:ff:ff"); //Your address here

BLEAddress phone1 = BLEAddress("ff:ff:ff:ff:ff:ff"); //Your address here
BLEAddress phone2 = BLEAddress("ff:ff:ff:ff:ff:ff"); //Your address here

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
  // For Serial Debugging
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
    }
};

void setup(){
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, port); 
  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true);
}

void setup_wifi(){
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected!");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("BLEPresence")) {
      Serial.println("connected");
      client.publish(topic,"BLETracker Conected"); //This should appear if you sub to your topic
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  BLEScanResults foundDevices = pBLEScan->start(BTScanTime, false);
  for (int i = 0; i < foundDevices.getCount(); i++){
    BLEAddress found = foundDevices.getDevice(i).getAddress();
    if (found.equals(tag1) || found.equals(phone1)){
      client.publish(topic, person1payload);
    }
    if (found.equals(tag2) || found.equals(phone2)){
      client.publish(topic, person2payload);
    }
  }
  
  client.loop();
  pBLEScan->clearResults();
  delay(5000); // Scan every 5 seconds
}

```