结合MQTT与RS485进行数据通讯
在现代工业自动化中,监测各种传感器的数据并实时传输至服务器是至关重要的。本文将介绍如何使用Python融合MQTT协议和RS485串口通信,实现设备数据的读取和网络传输。
MQTT简介
MQTT(Message Queuing Telemetry Transport)是一个轻量级的消息传输协议,广泛用于物联网设备间的通信。通过发布/订阅模式,设备可以向主题发布消息,同时也可以订阅主题以接收消息。
RS485简介
RS485是一种串行通信标准,它支持远距离和高速率的通信。在工业环境中,RS485通常用于连接传感器和控制器。
脚本功能概述
本脚本结合了MQTT的网络通信能力与RS485串口的数据读取功能,可以从RS485设备读取数据,并通过MQTT协议发送到服务器。同时,它还能订阅来自服务器的消息。
导入库
脚本首先导入必要的库:
paho.mqtt.client: 用于MQTT通信。
minimalmodbus: 用于RS485通信。
threading: 用于创建并行的执行线程。
配置MQTT
脚本配置了MQTT服务器的地址和端口,以及定义了订阅和发布的主题。
MQTT回调函数
on_connect: 当与MQTT服务器连接成功时调用,订阅一个主题。
on_message: 当收到订阅主题的消息时调用。
RS485配置
设置RS485设备的串口参数,并准备读取数据的命令帧。
数据读取和发布函数
定义了一个函数read_and_publish_data,它在一个循环中不断读取RS485设备的数据,并将数据格式化后发布到MQTT服务器。
主函数
在主函数中,创建并配置MQTT客户端,连接到服务器,并启动一个线程来执行read_and_publish_data函数。最后,调用client.loop_forever()开始循环,处理接收到的消息和保持连接。
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import minimalmodbus
import serial
import threading
import time
import json
# MQTT服务器地址和端口
HOST = "broker.emqx.io"
PORT = 1883
# 发布和订阅的主题
PUB_TOPIC = "test/topic/pub" # 修改为你的发布主题
SUB_TOPIC = "test/topic/sub" # 修改为你的订阅主题
# 当客户端收到来自服务器的CONNACK响应时的回调
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe(SUB_TOPIC) # 订阅主题
# 当从服务器接收到PUBLISH消息时的回调
def on_message(client, userdata, msg):
print(f"Message received on topic {msg.topic}: {str(msg.payload)}")
# 获取MQTT客户端实例
def getMQTTClient():
client = mqtt.Client()
return client
# 配置读取RS485设备的串口 ttyAMA2
instrument = minimalmodbus.Instrument('/dev/ttyAMA2', 0x01) # 0x01是设备地址
instrument.serial.baudrate = 9600 # RS485设备的波特率
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 1 # 超时时间
# 准备Modbus RTU的命令帧
addr = 0x01
cmd = 0x03
startAddr = 0x0000
dataLen = 0x0004
# 定义读取RS485设备并发布数据的函数
def read_and_publish_data(client):
while True:
try:
# 从RS485设备读取数据
data = instrument.read_registers(startAddr, dataLen, cmd) # 读取寄存器的内容
# 格式化读取到的数据
temp = data[0] / 10.0 # 将温度转换为十分之一摄氏度
x_speed = data[1] / 10.0 # 将速度转换为十分之一mm/s
y_speed = data[2] / 10.0
z_speed = data[3] / 10.0
# 构建将要发送的消息
payload_json = {
'temperature': temp,
'x_speed': x_speed,
'y_speed': y_speed,
'z_speed': z_speed
}
# 发布消息
client.publish(PUB_TOPIC, payload=json.dumps(payload_json), qos=1)
print('Sent data to MQTT server: ' + json.dumps(payload_json))
time.sleep(5)
except Exception as e:
print("Error:", e)
if __name__ == '__main__':
client = getMQTTClient()
client.on_connect = on_connect
client.on_message = on_message
# 连接 MQTT 服务器
client.connect(HOST, PORT, 60)
# 启动线程来读取RS485数据并发布
rs485_thread = threading.Thread(target=read_and_publish_data, args=(client,))
rs485_thread.start()
# 开始 MQTT 客户端的循环,处理接收到的消息和重新连接等
client.loop_forever()