在物联网应用中,MQTT(Message Queuing Telemetry Transport)是一种重要的通信协议,它为设备间的高效数据交换提供了可靠的基础。本文将介绍MQTT是什么以及其基本原理。
MQTT是一种轻量级的发布/订阅协议,旨在解决低带宽、不稳定网络和资源有限设备的通信需求。它采用简单的二进制消息格式,具有协议开销小、带宽消耗低的特点,非常适用于物联网设备,尤其是那些资源有限的设备,如传感器、嵌入式系统和移动设备。
MQTT的基本原理建立在发布/订阅模型上。在MQTT中,设备可以通过发布消息将数据发送到特定的主题(Topic),而其他设备可以通过订阅相应的主题来接收这些消息。这种发布/订阅机制使得设备能够实时地传输和接收数据,实现设备间的实时通信。
在MQTT中,有三个关键角色:发布者(Publisher)、订阅者(Subscriber)和代理服务器(Broker)。发布者负责将数据发布到特定主题,订阅者则订阅感兴趣的主题以接收数据。而代理服务器(也称为Broker)则充当中介,负责接收来自发布者的消息,并将其传递给订阅者。
MQTT的消息质量等级(QoS级别)确保了消息的可靠性和交付顺序。MQTT支持三种QoS级别:
- QoS 0:最多一次交付,消息不进行确认,可能会丢失或重复传输。
- QoS 1:至少一次交付,消息进行确认,确保消息至少传输一次,但可能会重复传输。
- QoS 2:只有一次交付,消息进行确认和去重,确保消息仅传输一次。
MQTT协议的简单性和可靠性使得它成为物联网应用中的首选通信协议。无论是智能家居、工业自动化还是能源管理,MQTT都广泛应用于各种场景。此外,许多物联网平台和服务提供商也提供对MQTT协议的支持,为开发者提供便捷的开发和管理工具。它的低开销、发布/订阅模式和可靠性保证使得MQTT在物联网应用中具有重要的地位和广泛的应用。
代理服务器(Broker):Mosquitto
本项目代理服务器(Broker)选择Mosquitto:
Mosquitto是一款轻量级的开源MQTT(Message Queuing Telemetry Transport)消息代理软件,最初由Eclipse IoT项目提供支持。
MQTT是一种轻量级、高效、基于发布/订阅模式的消息传递协议,广泛应用于物联网(IoT)和机器对机器(M2M)通信领域。Mosquitto提供了一个可扩展的、高性能的MQTT代理服务器,可以帮助开发人员在分布式系统中实现可靠的消息传递。
Mosquitto的特点包括:
- 轻量级和高效:Mosquitto使用C语言编写,占用系统资源非常少,可以在嵌入式系统上运行。同时,它还支持QoS(Quality of Service)服务质量控制,确保消息可靠传递。
- 安全性:Mosquitto支持TLS/SSL传输加密和客户端身份验证,保障消息传递的安全性。
- 易于集成:Mosquitto提供了多种编程语言的客户端库,包括C、Python、Java等,使得开发人员可以方便地将其集成到自己的应用程序中。
- 可扩展性:Mosquitto支持多个订阅者和发布者,并可通过多个代理构建分布式系统。
总之,Mosquitto是一个功能强大的MQTT代理软件,具有高效、可靠、安全、易于集成和可扩展等优点,非常适用于物联网和机器对机器通信领域。
官网地址:http://www.mosquitto.org
MQTT服务器地址:test.mosquitto.org
TCP 端口:1883
TCP/TLS 端口:8883
WebSockets 端口:8080
Websocket/TLS 端口:8081
树莓派接入物联网
关于树莓派初次使用环境搭建可以看我之前的文章:https://blog.csdn.net/HeX_Maker/article/details/130050637
要在树莓派上安装MQTT库,您可以使用Python的pip包管理器。以下是使用pip安装paho-mqtt库的步骤:
- 打开终端或SSH连接到树莓派。
- 确保您的树莓派已连接到互联网。
- 运行以下命令来安装paho-mqtt库:
pip install paho-mqtt
这将自动下载并安装paho-mqtt库及其依赖项。
- 安装完成后,您可以在Python代码中导入paho-mqtt库并开始使用它。以下是一个简单的示例:
import paho.mqtt.client as mqtt
import time
# MQTT连接参数
broker_address = "test.mosquitto.org"
broker_port = 1883
client_id = "ddde89aafe584efb8359eb7e20f69dca"
topic = "time"
# 创建MQTT客户端实例
client = mqtt.Client(client_id)
# 连接到MQTT代理
client.connect(broker_address, broker_port)
# 无限循环,每隔一段时间发送当前时间到MQTT主题
while True:
# 获取当前时间并转换为字符串
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# 将当前时间发布到MQTT主题
client.publish(topic, current_time)
# 等待5秒钟
time.sleep(5)
# 断开MQTT连接
client.disconnect()
Node-Red接入物联网
在左侧网络里找到“mqtt in”和“mqtt out” 分别代表接收和发送,如下图所示:
把“mqtt in” 拖入工作区后编辑MQTT服务器地址和TCP 端口即可:
树莓派通过物联网发送数
在本项目中树莓派传送的是传感器的温湿度数据,可以先看之前的DHT11连接树莓派教程:https://blog.csdn.net/HeX_Maker/article/details/130119821 以及:https://blog.csdn.net/HeX_Maker/article/details/130795190
import paho.mqtt.client as mqtt
import time
import RPi.GPIO as GPIO
# MQTT连接参数
broker_address = "test.mosquitto.org"
broker_port = 1883
client_id = "ddde89aafe584efb8359eb7e20f69dca"
topic = "time"
# 创建MQTT客户端实例
client = mqtt.Client(client_id)
# 连接到MQTT代理
client.connect(broker_address, broker_port)
def delayMicrosecond(t):
start,end=0,0
start=time.time()
t=(t-3)/1000000
while end-start<t:
end=time.time()
tmp0=[] # Used to store the read data
tmp1=[]
tmp2=[]
data0 = 17 # DHT11 BCM
data1 = 27
data2 = 22
a,b=0,0
def DHT11\_0():
GPIO.setup(data0, GPIO.OUT) # GPIO OUTPUT
GPIO.output(data0,GPIO.HIGH)
delayMicrosecond(10\*1000) # delay 10ms
GPIO.output(data0,GPIO.LOW)
delayMicrosecond(25\*1000) # delay 25ms
GPIO.output(data0,GPIO.HIGH)
GPIO.setup(data0, GPIO.IN) # GPIO INPUT
a=time.time() # Recording cycle start time
while GPIO.input(data0):
b=time.time() # time the record ended
if (b-a)>0.1: #Determine whether the cycle time exceeds 0.1 seconds to avoid the program from entering an infinite loop and getting stuck
break
a=time.time()
while GPIO.input(data0)==0:
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data0):
b=time.time()
if (b-a)>=0.1:
break
for i in range(40):
a=time.time()
while GPIO.input(data0)==0:
b=time.time()
if (b-a)>0.1:
break
delayMicrosecond(28) # delay 28 microseconds
if GPIO.input(data0): # After more than 28 microseconds, it is judged whether it is still at a high level
tmp0.append(1) # Record the received bit as 1
a=time.time()
while GPIO.input(data0): # Loop until the input is low
b=time.time()
if (b-a)>0.1:
break
else:
tmp0.append(0) # Record the received bit as 0
def DHT11\_1():
GPIO.setup(data1, GPIO.OUT)
GPIO.output(data1,GPIO.HIGH)
delayMicrosecond(10\*1000)
GPIO.output(data1,GPIO.LOW)
delayMicrosecond(25\*1000)
GPIO.output(data1,GPIO.HIGH)
GPIO.setup(data1, GPIO.IN)
a=time.time()
while GPIO.input(data1):