Arduino - MQTT

In this tutorial, we will learn how to use Arduino to send/receive data to MQTT broker using MQTT protocol. In detail, we will learn:

Arduino MQTT

We'll explore two different use cases:

Hardware Required

1×Arduino UNO R4 WiFi
1×USB Cable Type-C
1×(Recommended) Screw Terminal Block Shield for Arduino UNO R4
1×(Recommended) Breadboard Shield For Arduino UNO R4
1×(Recommended) Enclosure For Arduino UNO R4

Or you can buy the following sensor kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Please note: These are Amazon affiliate links. If you buy the components through these links, We will get a commission at no extra cost to you. We appreciate it.

About Arduino and MQTT

Assuming you're already familiar with the MQTT protocol. If not, please conduct research on the Internet. This tutorial focuses on programming Arduino to send and receive data using the MQTT protocol.

The below are use-cases of Arduino with MQTT:

  • Arduino connects to online MQTT broker, e.g.: online Mosquitto broker, AWS IoT...
  • Arduino connects to MQTT broker installed on your PC, e.g.: Mosquitto broker, HiveMQ broker
  • Arduino connects to MQTT broker installed on your Raspberry Pi, e.g.: Mosquitto broker
  • Arduino connects to MQTT broker installed on cloud: e.g.: Mosquitto or HiveMQ broker on AWS EC2

In this tutorial, we'll begin by quickly checking if Arduino can connect to an online Mosquitto broker. Arduino will publish and subscribe to this broker over the internet.

Next, we'll move on to installing the Mosquitto broker on our PC. We'll then connect Arduino to the MQTT broker installed on our PC, continuing to publish and subscribe data through this local broker.

Once you've completed this tutorial, you can explore further by learning about Arduino with MQTT in the following tutorials:

Connect Arduino to an online MQTT broker

In this part, we will learn how to connect Arduino to test.mosquitto.org, an online MQTT broker created by Mosquitto. Please note that this broker should be used for the testing purpose only.

Arduino Code

The below Arduino code does:

  • Connect to the MQTT broker
  • Subscribe to a topic
  • Periodically publish messages to the same topic that it subscribes
/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-mqtt */ #include <WiFiS3.h> #include <MQTTClient.h> #include <ArduinoJson.h> const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // CHANGE TO YOUR WIFI SSID const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // CHANGE TO YOUR WIFI PASSWORD const char MQTT_BROKER_ADRRESS[] = "test.mosquitto.org"; // CHANGE TO MQTT BROKER'S ADDRESS const int MQTT_PORT = 1883; const char MQTT_CLIENT_ID[] = "YOUR-NAME-arduino-001"; // CHANGE IT AS YOU DESIRE const char MQTT_USERNAME[] = ""; // CHANGE IT IF REQUIRED, empty if not required const char MQTT_PASSWORD[] = ""; // CHANGE IT IF REQUIRED, empty if not required // The MQTT topics that Arduino should publish/subscribe const char PUBLISH_TOPIC[] = "YOUR-NAME-arduino-001/loopback"; // CHANGE IT AS YOU DESIRE const char SUBSCRIBE_TOPIC[] = "YOUR-NAME-arduino-001/loopback"; // CHANGE IT AS YOU DESIRE const int PUBLISH_INTERVAL = 5000; // 5 seconds WiFiClient network; MQTTClient mqtt = MQTTClient(256); unsigned long lastPublishTime = 0; void setup() { Serial.begin(9600); int status = WL_IDLE_STATUS; while (status != WL_CONNECTED) { Serial.print("Arduino - Attempting to connect to SSID: "); Serial.println(WIFI_SSID); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // wait 10 seconds for connection: delay(10000); } // print your board's IP address: Serial.print("IP Address: "); Serial.println(WiFi.localIP()); connectToMQTT(); } void loop() { mqtt.loop(); if (millis() - lastPublishTime > PUBLISH_INTERVAL) { sendToMQTT(); lastPublishTime = millis(); } } void connectToMQTT() { // Connect to the MQTT broker mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network); // Create a handler for incoming messages mqtt.onMessage(messageHandler); Serial.print("Arduino - Connecting to MQTT broker"); while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { Serial.print("."); delay(100); } Serial.println(); if (!mqtt.connected()) { Serial.println("Arduino - MQTT broker Timeout!"); return; } // Subscribe to a topic, the incoming messages are processed by messageHandler() function if (mqtt.subscribe(SUBSCRIBE_TOPIC)) Serial.print("Arduino - Subscribed to the topic: "); else Serial.print("Arduino - Failed to subscribe to the topic: "); Serial.println(SUBSCRIBE_TOPIC); Serial.println("Arduino - MQTT broker Connected!"); } void sendToMQTT() { StaticJsonDocument<200> message; message["timestamp"] = millis(); message["data"] = analogRead(0); // Or you can read data from other sensors char messageBuffer[512]; serializeJson(message, messageBuffer); mqtt.publish(PUBLISH_TOPIC, messageBuffer); Serial.println("Arduino - sent to MQTT:"); Serial.print("- topic: "); Serial.println(PUBLISH_TOPIC); Serial.print("- payload:"); Serial.println(messageBuffer); } void messageHandler(String &topic, String &payload) { Serial.println("Arduino - received from MQTT:"); Serial.println("- topic: " + topic); Serial.println("- payload:"); Serial.println(payload); }

Quick Steps

  • If this is the first time you use Arduino Uno R4, see how to setup environment for Arduino Uno R4 on Arduino IDE.
  • Open Arduino IDE on your PC
  • Open the Library Manager by clicking on the Library Manager icon on the left navigation bar of Arduino IDE
  • Type MQTT on the search box, then look for the MQTT library by Joel Gaehwiler.
  • Click Install button to install MQTT library.
Arduino MQTT library
  • Type ArduinoJson on the search box, then look for the ArduinoJson library by Benoit Blanchon.
  • Click Install button to install ArduinoJson library.
Arduino Json library
  • Copy the above code and open with Arduino IDE
  • Replace the WiFi information (SSID and password) in the code with your own.
  • In the code, you will see the word 'YOUR-NAME' three times. Replace this word with your name or random characters (alphabet characters only, no spaces). This is necessary because if you do not make the change, there may be multiple people running this code at the same time, which could lead to conflicts because the MQTT client IDs and topics are the same for everyone.
  • Click Upload button on Arduino IDE to upload code to Arduino
  • Open the Serial Monitor
  • See the result on Serial Monitor.
COM6
Send
IP Address: 192.168.0.2 Arduino - Connecting to MQTT broker Arduino - Subscribed to the topic: YOUR-NAME-arduino-001/loopback Arduino - MQTT broker Connected! Arduino - sent to MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload:{"timestamp":11757,"data":255} Arduino - received from MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload: {"timestamp":11757,"data":255} Arduino - sent to MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload:{"timestamp":16896,"data":259} Arduino - received from MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload: {"timestamp":16896,"data":259}
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

As you can see, Arduino publishes messages to the MQTT broker, then receives back the same message. That is because the above code subscribes to the same topic that it publishes data to. If you do not want Arduino to receive the message that it publishes, simply make the SUBSCRIBE topic different from the PUBLISH topic.

Connect Arduino to the MQTT broker installed on your PC

Installing Mosquitto MQTT Broker

  • Install it on the D: drive instead of the C: drive. Avoid installing the Mosquitto broker on the C: drive to prevent potential issues.

Run Mosquitto MQTT broker

Now, let's check if the MQTT broker is functioning properly by following these steps:

  • Go to the directory where Mosquitto was installed. For instance: D:\Draft\mosquitto>
  • Make a new file named test.conf, copy the content below, and save it in that directory:
listener 1883 allow_anonymous true
  • Run a Command Prompt as Administrator on your PC. Let's call it Broker Window. Do not close it until the end of the tutorial.
Windows command prompt administrator
  • Run the below commands one by one:
cd /d D:\Draft\mosquitto mosquitto -v -c test.conf
  • You will see:
Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto -v -c test.conf 1710918939: mosquitto version 2.0.18 starting 1710918939: Config loaded from test.conf. 1710918939: Opening ipv6 listen socket on port 1883. 1710918939: Opening ipv4 listen socket on port 1883. 1710918939: mosquitto version 2.0.18 running
  • Open another Command Prompt as Administrator on your PC.
  • Find the IP address of your PC by running the below command:
ipconfig
Command Prompt
C:\WINDOWS\system32>ipconfig Windows IP Configuration Ethernet adapter: Subnet Mask . . . . . . . . . . . : 255.0.0.0 IPv4 Address. . . . . . . . . . . : 192.168.0.26 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . :
  • Write down the IP address for later use. In the above example: 192.168.0.26

Test if the Mosquitto Broker works

  • Open another Command Prompt as Administrator on your PC. Let's call it Subscriber Window
  • Subscribe to a topic by running the below commands one by one (replace by your IP address):
cd /d D:\Draft\mosquitto mosquitto_sub -h 192.168.0.26 -p 1883 -t arduino-001/send
  • Open another Command Prompt as Administrator on your PC. Let's call it Publisher Window
  • Publish a message to the same topic by running the below commands one by one (replace by your IP address):
cd /d D:\Draft\mosquitto mosquitto_pub -h 192.168.0.26 -p 1883 -t arduino-001/send -m "Hello, MQTT!"
  • You will see:
Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto_pub -h 192.168.0.26 -p 1883 -t arduino-001/send -m "Hello, MQTT!" D:\Draft\mosquitto>

You will see that message is forwarded to the Subscriber Window as follows:

Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto_sub -h 192.168.0.26 -p 1883 -t arduino-001/send Hello, MQTT!

Now, you installed successfully the Mosquitto MQTT broker on your PC. Please do NOT close three windows: Broker Window, Subscriber Window, and Publisher Window. We will use them next.

Arduino Code

The below Arduino code does:

  • Connect to the MQTT broker
  • Subscribe to a topic
  • Periodically publish messages to another topic
/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-mqtt */ #include <WiFiS3.h> #include <MQTTClient.h> #include <ArduinoJson.h> const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // CHANGE TO YOUR WIFI SSID const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // CHANGE TO YOUR WIFI PASSWORD //const char MQTT_BROKER_ADRRESS[] = "test.mosquitto.org"; // CHANGE TO MQTT BROKER'S ADDRESS const char MQTT_BROKER_ADRRESS[] = "192.168.0.26"; // CHANGE TO MQTT BROKER'S IP ADDRESS const int MQTT_PORT = 1883; const char MQTT_CLIENT_ID[] = "arduino-001"; // CHANGE IT AS YOU DESIRE const char MQTT_USERNAME[] = ""; // CHANGE IT IF REQUIRED, empty if not required const char MQTT_PASSWORD[] = ""; // CHANGE IT IF REQUIRED, empty if not required // The MQTT topics that Arduino should publish/subscribe const char PUBLISH_TOPIC[] = "arduino-001/send"; // CHANGE IT AS YOU DESIRE const char SUBSCRIBE_TOPIC[] = "arduino-001/receive"; // CHANGE IT AS YOU DESIRE const int PUBLISH_INTERVAL = 5000; // 5 seconds WiFiClient network; MQTTClient mqtt = MQTTClient(256); unsigned long lastPublishTime = 0; void setup() { Serial.begin(9600); int status = WL_IDLE_STATUS; while (status != WL_CONNECTED) { Serial.print("Arduino - Attempting to connect to SSID: "); Serial.println(WIFI_SSID); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // wait 10 seconds for connection: delay(10000); } // print your board's IP address: Serial.print("IP Address: "); Serial.println(WiFi.localIP()); connectToMQTT(); } void loop() { mqtt.loop(); if (millis() - lastPublishTime > PUBLISH_INTERVAL) { sendToMQTT(); lastPublishTime = millis(); } } void connectToMQTT() { // Connect to the MQTT broker mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network); // Create a handler for incoming messages mqtt.onMessage(messageHandler); Serial.print("Arduino - Connecting to MQTT broker"); while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { Serial.print("."); delay(100); } Serial.println(); if (!mqtt.connected()) { Serial.println("Arduino - MQTT broker Timeout!"); return; } // Subscribe to a topic, the incoming messages are processed by messageHandler() function if (mqtt.subscribe(SUBSCRIBE_TOPIC)) Serial.print("Arduino - Subscribed to the topic: "); else Serial.print("Arduino - Failed to subscribe to the topic: "); Serial.println(SUBSCRIBE_TOPIC); Serial.println("Arduino - MQTT broker Connected!"); } void sendToMQTT() { StaticJsonDocument<200> message; message["timestamp"] = millis(); message["data"] = analogRead(0); // Or you can read data from other sensors char messageBuffer[512]; serializeJson(message, messageBuffer); mqtt.publish(PUBLISH_TOPIC, messageBuffer); Serial.println("Arduino - sent to MQTT:"); Serial.print("- topic: "); Serial.println(PUBLISH_TOPIC); Serial.print("- payload:"); Serial.println(messageBuffer); } void messageHandler(String &topic, String &payload) { Serial.println("Arduino - received from MQTT:"); Serial.println("- topic: " + topic); Serial.println("- payload:"); Serial.println(payload); // You can process the incoming data as json object, then control something /* StaticJsonDocument<200> doc; deserializeJson(doc, payload); const char* message = doc["message"]; */ }

Quick Steps

  • Copy the above code and open with Arduino IDE
  • Replace the WiFi information (SSID and password) in the code with your own.
  • Replace the MQTT broker address in the code (domain name or IP address).
  • Click Upload button on Arduino IDE to upload code to Arduino

Send message from Arduino to PC via MQTT

Arduino codes publishes data to the MQTT topic arduino-001/send, Subscriber Window on PC subscribe that topic to receive the data.

  • Open the Serial Monitor, you will see Arduino periodically publish a message to a topic.
COM6
Send
IP Address: 192.168.0.2 Arduino - Connecting to MQTT broker Arduino - Subscribed to the topic: arduino-001/receive Arduino - MQTT broker Connected! Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":10708,"data":311} Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":15837,"data":298} Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":20965,"data":291} Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":26094,"data":286}
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Check the Subscriber Window, you will see that it receives the message published by Arduino as below:
Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto_sub -h 192.168.0.26 -p 1883 -t arduino-001/send Hello, MQTT! {"timestamp":10708,"data":311} {"timestamp":15837,"data":298} {"timestamp":20965,"data":291} {"timestamp":26094,"data":286}

Send message from PC to Arduino via MQTT

Arduino subscribes to the topic arduino-001/receive, Publisher Window on PC publish a message to that topic to send it to the Arduino.

  • Publish a message to the topic that Arduino subscribed by running the following command on Publisher Window:
mosquitto_pub -h 192.168.0.26 -p 1883 -t arduino-001/receive -m "Hello, Arduino!"
  • You will see this message is received by Arduino on Serial Monitor as below:
COM6
Send
Arduino - received from MQTT: - topic: arduino-001/receive - payload: Hello, Arduino!
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Video Tutorial

We are considering to make the video tutorials. If you think the video tutorials are essential, please subscribe to our YouTube channel to give us motivation for making the videos.

The Best Arduino Starter Kit

※ OUR MESSAGES