MQTT is a protocol that specifically sends data from devices of the Internet of Things and is supported by most microcontrollers and systems. To use Raspberry Pi MQTT communication, not much is needed, which is why this type of transmission is very interesting. In addition, it is really easy to use.
In this tutorial, we install a Raspberry Pi MQTT broker, whereupon we receive and send data. We can either use several Raspberry Pi’s for testing or just use a single device.
Accessory
This tutorial works without much additional hardware. However, you either have to have at least one Raspberry Pi 3 (alternatively a Model Zero W) or connect a wifi stick to your Raspberry Pi to use MQTT.
Other devices such as an ESP8266 can also communicate using MQTT. This is possible with Raspberry Pi’s as well as other devices. Also for the NodeMCU there are ready-made packages.
What is MQTT?
Some may wonder what MQTT should be. To quote the official MQTT page:
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.
It is therefore a standardized network protocol with which short messages / commands can be transmitted. The big advantage is that the built-in wifi adapters (for example in the Raspberry Pi or in the ESP8266) are used for the internet connection. More accessories and complicated wiring is not necessary! This makes it possible to send the data via the local network or the Internet.
In detail, the transfer consists of three different components:
- Publisher: Sends messages.
- Broker: Forwards messages to registered subscribers.
- Subscriber: Receives messages through the broker.
Raspberry Pi MQTT Server – Install and test Mosquitto
There are several applications that can be used to send and receive through MQTT, but the simplest on the Raspberry Pi is probably Mosquitto. We will install this on the Raspberry Pi first:
sudo apt-get install -y mosquitto mosquitto-clients
After installation, a Mosquitto server is started automatically. We open a subscriber in the channel “test_channel” waiting for messages:
mosquitto_sub -h localhost -v -t test_channel
The channel is here like a frequency, on which one hears. For example, different data may be sent in different channels (e.g., temperature, humidity, brightness, etc.).
In order to simply transfer data, we can either use the same Raspberry Pi (open new terminal / SSH connection) or send the data from another Pi. If we use the same Raspberry Pi, use is easily possible. For this we simply send a test message (as publisher) in the same channel:
mosquitto_pub -h localhost -t test_channel -m "Hello Raspberry Pi"
Otherwise you have to specify the internal IP address (eg 192.168.1.5) of the recipient instead of “localhost”. On the receiver side, the message should appear soforn.
Raspberry Pi MQTT data exchange with Python
The communication is super easy, as we have seen. In order for us to be able to use the whole thing from scripts, we want to make it available to Python. For this purpose, we first install a library via the Python package manager (for Python3 also use pip3):
sudo pip install paho-mqtt
Alternatively (for example, if the package could not be properly installed) you can also install it manually:
git clone https://github.com/eclipse/paho.mqtt.python.git cd paho.mqtt.python python setup.py install
We start with the receiver. For this we create a new file with the content:
sudo nano mqtt_subscriber.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import paho.mqtt.client as mqtt MQTT_SERVER = "localhost" MQTT_PATH = "test_channel" # The callback for when the client receives a CONNACK response from the server. def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. client.subscribe(MQTT_PATH) # The callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) # more callbacks, etc client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect(MQTT_SERVER, 1883, 60) # Blocking call that processes network traffic, dispatches callbacks and # handles reconnecting. # Other loop*() functions are available that give a threaded interface and a # manual interface. client.loop_forever() |
After saving and closing (CTRL + O, CTRL + X) we execute the file:
sudo python mqtt_subscriber.py
Either you send a command as usual by Shell Command, or we also create a Python Sender / Publisher.
The publisher’s code looks like this (create a new file and then run it, keeping in mind the correct IP address):
1 2 3 4 5 6 7 |
import paho.mqtt.publish as publish MQTT_SERVER = "192.168.1.5" MQTT_PATH = "test_channel" publish.single(MQTT_PATH, "Hello World!", hostname=MQTT_SERVER) |
That’s it! Now you can include the appropriate parts in your scripts and receive or send MQTT messages from other Raspberry Pi’s. Of course, this is not just limited to Raspberry Pi’s because the messages can also come from or be addressed to other devices.
Other ways to communicate with Raspberry Pi’s
Of course, MQTT is far from the only way to exchange data. If you have a system with its own OS such. Raspbian can be established using SSH connections and, for example, send via SCP files. However, the devices must have a network connection.
Another possibility without internet connection are normal radio transmitters and receivers. Here is e.g. The 433 MHz radio transmission is very popular because the modules are very cheap and many devices such as radio-controlled sockets or garage doors are compatible with it. However, this transfer is limited to 24 bits, which is not very much.
More data per message can be transmitted via 2.4 GHz radio transmission. This transfer differs from MQTT because extra modules are used. However, it is also possible to send commands or messages to Arduinos.
30 Comments
hi,
can i communicate using my internet router (Dlink).
what changes should i make ?
thank you
You want to communicate through or with the router?
through the router.
and one more thing how do i subscribe to multiple topics.
thanks
Yes, of course. Any router should be fine. Just use the subscribe command several times.
Thank you so much
This code helped me a lot in my project ??
You are welcome 🙂
hi,
i wanted one more help .
how do we connect to multiple ip address ?
i have 2 topics on different raspberry pi
and im connecting them to a laptop
i am just able to connect to the first client.connect(ip1)
and not the client.connect(ip2)
hi,
can i communicate rpi3 and app phone via wifi? I need stream data with phone accelerometr to rpi3, it is possible?
I don’t think that your Phone supports MQTT…
When I tried the code on this page, I used the app MQTTool on my iPhone 5S, – and it worked!
There are several MQTT apps for iPhone, but so far I have just tested MQTTool, Mqtt buddy (a bit hard to understand), and IoT Manager (crashes sometimes and hard to get to connect).
So try search for “mqtt client” at the App Store.
For now I’m trying to find/learn how to get a notification-signal on my iPhone when I get a message from the mqtt-server/broker. No luck yet.
Felix: Thank you for the guide! You made me understand how mqtt works!
Hi I need complete information about using mqtt established msg send and received using telegram app with raspberry pi can u pls send the full coding part pls….
I need it too.
Could you please tell us how to send the sensors data to another pc using mqtt
You need to process sensor data and send in mqqt message. There is python code out there for both, need to merge to get what you want. I am in process of trying to do that.
Hi,
Can i communicate between my windows PC and Rpi3- I have installed mosquitto in both
Can a mqtt send data to raspi lcd at scheduled time?
Hello, i am having an issue with trying to communicate with the two python scripts.
I am using them both in two different terminals in the same raspberry pi, but none of them is sending or accepting anything.
When I try to test the communication with commands only it works fine, but not with python scripts 🙁
Fixed it, thanks
Any one can send me the code for MQTT Client Protocol in Raspberry in C lang for storing data in the server.
hi, I have connected one raspberry pi zero W with raspberry pi 3b and sending data using MQTT protocol. Further, I want to connect two raspberry pi zero and send both on their data to raspberry 3b. could you help with the code on raspberry 3b
Really helpful – thank you for explaining it so clearly.
hi i have problem to install setup.py please help me
error: can’t create or remove files in install directory
The following error occurred while trying to add or remove files in the
installation directory:
[Errno 13] Permission denied: ‘/usr/local/lib/python2.7/dist-packages/test-easy-install-3159.write-test’
The installation directory you specified (via –install-dir, –prefix, or
the distutils default setting) was:
/usr/local/lib/python2.7/dist-packages/
Perhaps your account does not have write access to this directory? If the
installation directory is a system-owned directory, you may need to sign in
as the administrator or “root” account. If you do not have administrative
access to this machine, you may wish to choose a different installation
directory, preferably one that is listed in your PYTHONPATH environment
variable.
For information on other options, you may wish to consult the
documentation at:
https://setuptools.readthedocs.io/en/latest/easy_install.html
Please make the appropriate changes for your system and try again.
What is the maximum number of devices that can be connected in a network?
I keep getting the following error whenever I try to run they mqtt_subscriber.py file. Any help would be greatly appreciated.
Traceback (most recent call last):
File “mqtt_subscriber.py”, line 12, in
client.subscribe(MQTT_PATH)
NameError: name ‘client’ is not defined
I a getting the same error – did you find a solution ?
Sorry, with this protocol, can i send/receive data from two raspberry pi separated one from the other 328 feet (100mts)? Which is the best IoT protocol used in this devices for transmitting data between two raspberry in this sense?
Thanks,
Sure, if they are both connected to a / the same network.
—————————————————————————
ConnectionRefusedError Traceback (most recent call last)
in
5 import time
6 while True:
—-> 7 publish.single(MQTT_PATH, “Hello World!”, hostname=MQTT_SERVER) #send data continuously every 3 seconds
8 print(“sent”)
9 time.sleep(3)
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttpublish.py in single(topic, payload, qos, retain, hostname, port, client_id, keepalive, will, auth, tls, protocol, transport, proxy_args)
230
231 multiple([msg], hostname, port, client_id, keepalive, will, auth, tls,
–> 232 protocol, transport, proxy_args)
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttpublish.py in multiple(msgs, hostname, port, client_id, keepalive, will, auth, tls, protocol, transport, proxy_args)
165 client.tls_set_context(tls)
166
–> 167 client.connect(hostname, port, keepalive)
168 client.loop_forever()
169
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttclient.py in connect(self, host, port, keepalive, bind_address, bind_port, clean_start, properties)
939 self.connect_async(host, port, keepalive,
940 bind_address, bind_port, clean_start, properties)
–> 941 return self.reconnect()
942
943 def connect_srv(self, domain=None, keepalive=60, bind_address=””,
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttclient.py in reconnect(self)
1073 self._messages_reconnect_reset()
1074
-> 1075 sock = self._create_socket_connection()
1076
1077 if self._ssl:
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttclient.py in _create_socket_connection(self)
3544 return socks.create_connection(addr, source_address=source, timeout=self._keepalive, **proxy)
3545 else:
-> 3546 return socket.create_connection(addr, source_address=source, timeout=self._keepalive)
3547
3548
~AppDataLocalProgramsPythonPython36-32libsocket.py in create_connection(address, timeout, source_address)
722
723 if err is not None:
–> 724 raise err
725 else:
726 raise error(“getaddrinfo returns an empty list”)
~AppDataLocalProgramsPythonPython36-32libsocket.py in create_connection(address, timeout, source_address)
711 if source_address:
712 sock.bind(source_address)
–> 713 sock.connect(sa)
714 # Break explicitly a reference cycle
715 err = None
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
28
import paho.mqtt.publish as publish
MQTT_SERVER = “192.168.43.28”
MQTT_PATH = “test_channel”
publish.single(MQTT_PATH, “Hello World!”, hostname=MQTT_SERVER)
—————————————————————————
ConnectionRefusedError Traceback (most recent call last)
in
4 MQTT_PATH = “test_channel”
5
—-> 6 publish.single(MQTT_PATH, “Hello World!”, hostname=MQTT_SERVER)
7
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttpublish.py in single(topic, payload, qos, retain, hostname, port, client_id, keepalive, will, auth, tls, protocol, transport, proxy_args)
230
231 multiple([msg], hostname, port, client_id, keepalive, will, auth, tls,
–> 232 protocol, transport, proxy_args)
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttpublish.py in multiple(msgs, hostname, port, client_id, keepalive, will, auth, tls, protocol, transport, proxy_args)
165 client.tls_set_context(tls)
166
–> 167 client.connect(hostname, port, keepalive)
168 client.loop_forever()
169
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttclient.py in connect(self, host, port, keepalive, bind_address, bind_port, clean_start, properties)
939 self.connect_async(host, port, keepalive,
940 bind_address, bind_port, clean_start, properties)
–> 941 return self.reconnect()
942
943 def connect_srv(self, domain=None, keepalive=60, bind_address=””,
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttclient.py in reconnect(self)
1073 self._messages_reconnect_reset()
1074
-> 1075 sock = self._create_socket_connection()
1076
1077 if self._ssl:
~AppDataLocalProgramsPythonPython36-32libsite-packagespahomqttclient.py in _create_socket_connection(self)
3544 return socks.create_connection(addr, source_address=source, timeout=self._keepalive, **proxy)
3545 else:
-> 3546 return socket.create_connection(addr, source_address=source, timeout=self._keepalive)
3547
3548
~AppDataLocalProgramsPythonPython36-32libsocket.py in create_connection(address, timeout, source_address)
722
723 if err is not None:
–> 724 raise err
725 else:
726 raise error(“getaddrinfo returns an empty list”)
~AppDataLocalProgramsPythonPython36-32libsocket.py in create_connection(address, timeout, source_address)
711 if source_address:
712 sock.bind(source_address)
–> 713 sock.connect(sa)
714 # Break explicitly a reference cycle
715 err = None
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
I am Getting this error how can i solve it?
Can i use this protocol to done communication done between 2 raspberry pi’s connected to a different network?
FYI, with the latest version of MQTT, you will need to edit the mosquitto.conf file as follows:
allow_anonymous true
listener 1883
Both lines are necessary to go beyond localhost use.
You can also configure users and passwords in the mosquitto.conf instead of allowing anonymous users, but I haven’t experimented with that yet.
More detail here: https://github.com/eclipse/mosquitto/issues/1985