目前多个HaaS设备( HaaS100, HaaS506,HaaS600 )均支持485接口,下面我们以两个 HaaS100 为例来演示如何基于 Modbus 协议实现设备间通信。
案例中我们以左边的板子为主机,右边的板子为从机,实现两个设备的命令发送及响应。更多的设备均可以通过 Modbus 总线连接,这里我们不做更多扩展。
# -*- encoding: utf-8 -*-
import time
import usys as sys
import modbus as mb
serial_port = 1 # 485端口号,haas100使用的端口为1
serial_baudrate = 9600 # 波特率
slave_addr = 1 # 从机设备地址
reg_addr = 1 # 寄存器地址
reg_value = 2 # 寄存器数据
req_reg_cnt = 10 # 寄存器数目
resp_timeout = 200 # 响应等待时间,单位为毫秒(ms
rw_timeout = 500 # 串口读写超时时间,单位为毫秒(ms
loop_cnt = 5
def mb_master():
mb.init(serial_port, serial_baudrate, mb.PARITY_NONE, resp_timeout)
loop = 0
while(loop < loop_cnt):
res = mb.writeHoldingRegister(
slave_addr, reg_addr, reg_value, rw_timeout)
print('modbus master write Holding Reg result:', res)
data = bytearray(req_reg_cnt * 2)
res = mb.readHoldingRegisters(
slave_addr, reg_addr, req_reg_cnt, data, -1)
print('modbus master read Holding Regs result:', res)
loop = loop + 1
time.sleep(1)
mb.deinit()
def mb_slave():
mb.init(serial_port, serial_baudrate, mb.PARITY_NONE, 100)
while True:
data = mb.recv()
status = data[0]
rx = data[1]
# 收到有效数据,处理并响应请求
if(status == 0):
# 提取数据并判断是否为发送给自己
if(rx[0] == slave_addr):
if rx[1] == 0x06:
resp = bytearray(5)
resp[0] = rx[1]
resp[1] = rx[2]
resp[2] = rx[3]
resp[3] = rx[4]
resp[4] = rx[5]
elif rx[1] == 0x03:
# 填充假数据作为响应数据
resp = bytearray(req_reg_cnt * 2 + 2)
resp[0] = rx[1]
resp[1] = req_reg_cnt * 2
for i in range(req_reg_cnt):
resp[i*2+2] = 0
resp[i*2+3] = i
else:
print('unsupported cmd for demo')
print('resp data:', resp)
mb.send(slave_addr, resp, 100)
mb.deinit()
if __name__ == '__main__':
if(len(sys.argv) == 2):
config = sys.argv[1]
if(config == 'master'):
mb_master()
elif(config == 'slave'):
mb_slave()
else:
print('Should specifiy master or slave')
在主机设备上运行命令:
python /data/pyamp/main.py master
在从机设备上运行命令:
python /data/pyamp/main.py slave
最终可以从主机从机上得到不同的输出:
主机输出:
(ash:/data)# python /data/pyamp/main.py master
Welcome to MicroPython
modbus master write Holding Reg result: (0, 1, 2, 0)
modbus master read Holding Regs result: (0, 20)
modbus master write Holding Reg result: (0, 1, 2, 0)
modbus master read Holding Regs result: (0, 20)
modbus master write Holding Reg result: (0, 1, 2, 0)
modbus master read Holding Regs result: (0, 20)
modbus master write Holding Reg result: (0, 1, 2, 0)
modbus master read Holding Regs result: (0, 20)
modbus master write Holding Reg result: (0, 1, 2, 0)
modbus master read Holding Regs result: (0, 20)
(ash:/data)# python /data/pyamp/main.py slave
Welcome to MicroPython
[ 108.558]<E>modbusm frame is too short or CRC error
[ 108.558]<E>modbus Failed to disassemble frame
resp data: bytearray(b'\x06\x00\x01\x00\x02')
resp data: bytearray(b'\x03\x14\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\t')
resp data: bytearray(b'\x06\x00\x01\x00\x02')
resp data: bytearray(b'\x03\x14\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\t')
resp data: bytearray(b'\x06\x00\x01\x00\x02')
resp data: bytearray(b'\x03\x14\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\t')
resp data: bytearray(b'\x06\x00\x01\x00\x02')
resp data: bytearray(b'\x03\x14\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\t')
resp data: bytearray(b'\x06\x00\x01\x00\x02')
resp data: bytearray(b'\x03\x14\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\t')