从RS485设备读取数据并通过ttyAMA1串口打印
源码下载,无需积分
树莓派从RS485设备读取信息
配置RS485通讯
RS485是一种差分信号通讯标准,通常需要一个转换器(如MAX485)来连接到树莓派的UART接口。这需要硬件支持。
构建Modbus RTU帧
地址(addr)、命令(cmd)、起始地址(startAddr)和数据长度(dataLen),这些是Modbus RTU协议的参数。
使用两个串口
从ttyAMA2读取数据,然后通过ttyAMA1打印出来。需要同时配置两个串口。
安装依赖库
pip install minimalmodbus
代码
import minimalmodbus
import serial
import time
# 配置读取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 # 超时时间
"""
# 设备2:配置读取RS485设备的串口 ttyAMA2
instrument2 = minimalmodbus.Instrument('/dev/ttyAMA2', 0x02) # 0x02是设备地址
instrument2.serial.baudrate = 9600 # RS485设备的波特率
instrument2.serial.bytesize = 8
instrument2.serial.parity = serial.PARITY_NONE
instrument2.serial.stopbits = 1
instrument2.serial.timeout = 1 # 超时时间
"""
# 准备Modbus RTU的命令帧
addr = 0x01
cmd = 0x03
startAddr = 0x0000
dataLen = 0x0004
# 配置打印信息的串口 ttyAMA1
ser = serial.Serial(
port='/dev/ttyAMA1', # 更改为 ttyAMA1 端口
baudrate=115200, # 设置波特率
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
try:
# 从RS485设备读取数据
data = instrument.read_registers(startAddr, dataLen, cmd) # 读取寄存器的内容
print(f"Data read from RS485 device: {data}")
# 将读取的数据发送到ttyAMA1
for value in data:
ser.write(f"{value}\n".encode()) # 发送数据,转换为字节字符串
time.sleep(0.1) # 稍微等待,确保数据完全发送
except Exception as e:
print("Error:", e)
finally:
ser.close() # 关闭ttyAMA1串口
instrument.serial.close() # 关闭ttyAMA2串口
按照特定规则打印代码
import minimalmodbus
import serial
import time
# 配置读取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 # 超时时间
"""
# 设备2:配置读取RS485设备的串口 ttyAMA2
instrument2 = minimalmodbus.Instrument('/dev/ttyAMA2', 0x02) # 0x02是设备地址
instrument2.serial.baudrate = 9600 # RS485设备的波特率
instrument2.serial.bytesize = 8
instrument2.serial.parity = serial.PARITY_NONE
instrument2.serial.stopbits = 1
instrument2.serial.timeout = 1 # 超时时间
"""
# 准备Modbus RTU的命令帧
addr = 0x01
cmd = 0x03
startAddr = 0x0000
dataLen = 0x0004
# 配置打印信息的串口 ttyAMA1
ser = serial.Serial(
port='/dev/ttyAMA1', # 更改为 ttyAMA1 端口
baudrate=115200, # 设置波特率
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
try:
# 从RS485设备读取数据
data = instrument.read_registers(startAddr, dataLen, cmd) # 读取寄存器的内容
print(f"Data read from RS485 device: {data}")
# 将读取的数据发送到ttyAMA1
for value in data:
ser.write(f"{value}\n".encode()) # 发送数据,转换为字节字符串
time.sleep(0.1) # 稍微等待,确保数据完全发送
# 格式化读取到的数据
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
# 构造消息字符串
formatted_message = f"temp:{temp:.1f}℃; X:{x_speed:.1f}mm/s; Y:{y_speed:.1f}mm/s; Z:{z_speed:.1f}mm/s"
# 打开 ttyAMA1 串口进行写入
with serial.Serial('/dev/ttyAMA1', 115200, timeout=1) as ser:
ser.write(formatted_message.encode()) # 发送格式化后的数据
print("Message sent through ttyAMA1:", formatted_message)
except Exception as e:
print("Error:", e)
finally:
ser.close() # 关闭ttyAMA1串口
instrument.serial.close() # 关闭ttyAMA2串口
循环查询代码-间隔1s
import minimalmodbus
import serial
import time
# 配置读取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 # 超时时间
"""
# 设备2:配置读取RS485设备的串口 ttyAMA2
instrument2 = minimalmodbus.Instrument('/dev/ttyAMA2', 0x02) # 0x02是设备地址
instrument2.serial.baudrate = 9600 # RS485设备的波特率
instrument2.serial.bytesize = 8
instrument2.serial.parity = serial.PARITY_NONE
instrument2.serial.stopbits = 1
instrument2.serial.timeout = 1 # 超时时间
"""
# 准备Modbus RTU的命令帧
addr = 0x01
cmd = 0x03
startAddr = 0x0000
dataLen = 0x0004
# 配置打印信息的串口 ttyAMA1
ser = serial.Serial(
port='/dev/ttyAMA1', # 更改为 ttyAMA1 端口
baudrate=115200, # 设置波特率
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
while True:
try:
# 从RS485设备读取数据
data = instrument.read_registers(startAddr, dataLen, cmd) # 读取寄存器的内容
print(f"Data read from RS485 device: {data}\r\n")
"""
# 将读取的数据发送到ttyAMA1
for value in data:
ser.write(f"{value}".encode()) # 发送数据,转换为字节字符串
time.sleep(0.1) # 稍微等待,确保数据完全发送
"""
# 格式化读取到的数据
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
# 构造消息字符串
formatted_message = f"temp:{temp:.1f}℃; X:{x_speed:.1f}mm/s; Y:{y_speed:.1f}mm/s; Z:{z_speed:.1f}mm/s\r\n"
# 打开 ttyAMA1 串口进行写入
with serial.Serial('/dev/ttyAMA1', 115200, timeout=1) as ser:
ser.write(formatted_message.encode()) # 发送格式化后的数据
print("Message sent through ttyAMA1:", formatted_message)
time.sleep(1)
except Exception as e:
print("Error:", e)
finally:
ser.close() # 关闭ttyAMA1串口
instrument.serial.close() # 关闭ttyAMA2串口