本身我不是做PLC领域的,但正好有一个项目需要提供一个modbus接口,查阅了很多资料,发现主要都是在讲原理和客户端的实现,我这里就给大家提供一个主机和从机的通信实验案例吧。
连接好两个COM口
为了方便实验,这里我们用一个VSPD 7.2软件先为电脑提供两个COM口,并让两个COM口相连,打开软件,操作的方法如下:

添加完成以后,点开设备管理器,能看到下面的COM2和COM5相连
下载对应的pip安装相关的库
pip install modbus_tk pyserial
首先是从机的代码,我这里是写了一个温湿度的案例,让主机可以访问解析数据。
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import serial
import random
import time
# 串口设置
PORT = 'COM5' # 根据实际情况修改串口名称 COM5是下位机
def get_temperature_and_humidity():
"""模拟获取温度和湿度的函数"""
temperature = random.uniform(20.0, 30.0) # 模拟温度数据
humidity = random.uniform(30.0, 60.0) # 模拟湿度数据
return temperature, humidity
def main():
logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")
# 创建 Modbus RTU 从机服务器
server = modbus_rtu.RtuServer(serial.Serial(PORT, baudrate=9600, bytesize=8, parity='N', stopbits=1))
try:
logger.info("Modbus RTU server is running...")
server.start()
# 创建从机,地址为1
slave_1 = server.add_slave(1)
# 添加保持寄存器 (Holding Registers),假设温度和湿度分别映射到地址 0 和 1
slave_1.add_block('0', cst.HOLDING_REGISTERS, 0, 2) # 地址0开始,2个寄存器(一个存温度,一个存湿度)
while True:
# 获取当前温度和湿度
temperature, humidity = get_temperature_and_humidity()
# 将温度和湿度写入寄存器
slave_1.set_values('0', 0, [int(temperature * 10), int(humidity * 10)]) # 存储时放大10倍(例如20.3 -> 203)
# 每隔1秒更新一次数据
time.sleep(1)
except KeyboardInterrupt:
pass
finally:
server.stop()
if __name__ == "__main__":
main()
然后是主机的代码,负责向从机发送指令并解析出温度湿度。
import modbus_tk
from modbus_tk import modbus_rtu
import serial
import time
# 串口设置
PORT = 'COM2' # 根据实际情况修改串口名称,COM2是上位机
def main():
logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")
# 创建 Modbus RTU 主机客户端
client = modbus_rtu.RtuMaster(serial.Serial(PORT, baudrate=9600, bytesize=8, parity='N', stopbits=1))
client.set_timeout(1.0) # 设置超时时间为1秒
try:
logger.info("Modbus RTU client is running...")
while True:
# 读取从机 1 的保持寄存器(地址 0 和 1,分别存储温度和湿度)
response = client.execute(1, modbus_tk.defines.READ_HOLDING_REGISTERS, 0, 2)
# 获取返回的数据
temperature_raw = response[0]
humidity_raw = response[1]
# 将数据恢复为实际的温度和湿度
temperature = temperature_raw / 10.0
humidity = humidity_raw / 10.0
print(f"Temperature: {temperature}°C, Humidity: {humidity}%")
# 每隔1秒读取一次数据
time.sleep(1)
except KeyboardInterrupt:
pass
finally:
client.close()
if __name__ == "__main__":
main()
运行时要先运行从机的代码,在运行主机的代码,就可以看到结果了。
这是从机代码的运行结果:

这是主机代码的运行结果:

通过报文获取数据
也可以只运行从机代码,通过串口调试助手发送指令获取数据,我这里从机是使用的COM5,我用串口调试助手打开COM2,设置如下:

主机发送报文获取温度湿度01 03 00 00 00 02 C4 0B
01: 从机地址 103: 功能码,表示读取保持寄存器00 00: 寄存器起始地址 000 02: 读取 2 个寄存器C4 0B: CRC 校验码,确保数据的传输正确性。
可以收到从机返回的温度湿度报文01 03 04 01 1A 01 5F 9B A0:

01: 从机地址 103: 功能码,表示读取保持寄存器04: 字节数,表示数据部分为 4 字节01 1A: 第一个寄存器的数据,十进制值为25501 5F: 第二个寄存器的数据,十进制值为4929B A0: CRC 校验码,确保数据正确传输
表示当前的测量出的温度是25.5℃湿度是49.2%
4627

被折叠的 条评论
为什么被折叠?



