RK3568实现Modbus通信

2 篇文章 0 订阅
1 篇文章 0 订阅

背景

本次任务内容是在RK3568这块板子上实现Modbus RTU和TCP这两种类型的主机及从机通信,其目的就是通过串口获取或者上送采集数据,经过半天的努力终于完成了以上任务。
接下来就对这两种类型进行逐个介绍,这里我们是基于Python的modbus_tk这个库来实现的,如果你的板子还没有这个库,可通过如下指令进行安装。

pip install modbus_tk

Modbus RTU

对于该类型的协议这里不多做介绍,实际上对于串口modbus_tk还是基于serial这个库的实现,因此,我们可先通过serial库验证串口是否通了,建议可按照如下顺序进行排查:
1.直接通过指令验证

echo TestCode > /dev/ttysWK0

2.通过serial接口验证

ser = serial.Serial('/dev/ttysWK0', 9600)
success_bytes = ser.write(b'This is data for test\r\n') 

3.使用modbus_tk库实现最终的Modbus通信

Modbus RTU主机

import sys
import serial
import modbus_tk.modbus
import modbus_tk.defines as cst
import modbus_tk.modbus_rtu as modbus_rtu
     
#打开Modbus主机     
master = modbus_rtu.RtuMaster(serial.Serial(port='/dev/ttysWK0', baudrate= 9600, bytesize=8, parity='N', stopbits=1))
master.open
master.set_timeout(3)
master.set_verbose(True)

#发送保持寄存器读取指令
master.execute(1, cst.READ_HOLDING_REGISTERS, 1, 5)	

Modbus RTU从机

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import serial
import time

#打开Modbus从机
PORT = '/dev/ttysWK0'
modbusServ = modbus_rtu.RtuServer(serial.Serial(PORT),baudrate=9600,bytesize=8, parity='N', stopbits=1, xonxoff=0)

#启动从机服务器
modbusServ.start()

#创建从机设备
slave_1 = modbusServ.add_slave (1)
slave_1.add_block ("a",cst.ANALOG_INPUTS,200, 7)
slave_2 = modbusServ.add_slave(2)
slave_2.add_block ("b",cst.HOLDING_REGISTERS,200,7)
slave_5 = modbusServ.add_slave(5)
slave_5.add_block("c",cst.COILS,0,7)

#设定本地变量地址数值
while True:
        slave_1.set_values ("a",200,1)
        slave_1.set_values ("a",201,2)
        slave_1.set_values ("a",202,3)
        slave_1.set_values ("a",203,4)
        slave_1.set_values ("a",204,5)
        slave_1.set_values ("a",205,6)
        slave_1.set_values ("a",206,7)
        time.sleep(0.1)

Modbus TCP

顾名思义,这种类型的协议是基于TCP协议的,属于搭载在网络上的Modbus通信,这种类型依旧是基于modbus_tk的实现。

Modbus TCP主机

主机在以太网中的套接字属于客户端,主动去连接服务器(从机),实现代码如下:

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp

#可使用默认的502作为协议端口
master = modbus_tcp.TcpMaster(host="192.168.200.65")
#也可以指定其它端口作为主机端口
#master = modbus_tcp.TcpMaster('192.168.200.65', 503)

master.set_timeout(5.0)

#执行主机发送--读取多个保持寄存器数值
master.execute(1,cst.READ_HOLDING_REGISTERS,0, 4)

注:这里所涉及的hook知识由于暂时没有用到,所以目前没有做研究。

Modbus TCP从机

从机是服务器角色,需要在本地建立,代码如下:

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp

#创建从机
server = modbus_tcp.TcpServer(address='127.0.0.1',port=503)
#也可不指定端口,使用默认的502端口
#server = modbus_tcp.TcpServer(address='127.0.0.1')

server.start()
#添加从机设备
slave1 = server.add_slave(1)
slave1.add_block('a', cst.HOLDING_REGISTERS, 0, 100) 
slave1.add_block('c', cst.COILS, 0, 100)

端口占用

由于涉及到以太网,又是基于Socket的连接,必然会遇到之前打开过的端口由于应用关闭或者重启时,端口并未被释放掉而导致再次打开应用时提示端口已被占用,因此,我们需要通过一段代码来主动释放被占用的端口,如下:

import os
import re

def kill_process(port):
    ret = os.popen("netstat -nao|findstr " + str(port))
    #解码方式为"gbk",否则输出乱码
    str_list = ret.read().decode('gbk')
 
    ret_list = re.split('',str_list)
    try:
        process_pid = list(ret_list[0].split())[-1]
        os.popen('taskkill /pid ' + str(process_pid) + ' /F')	#释放
    except:
        #未使用

总结

到此也就完成了Modbus的RTU和TCP的所有实现工作,有了协议的支持实现仅是基础,后续还要对寄存器数据以及应用层协议进行定义,在该层协议的基础上二次开发应用,这才是最重要也是最复杂的,毕竟Python已经通过库的形式简化了我们的很多工作。
需要注意,以上的参考代码都是基本的实现,并没有增加保护和检查以及异常识别机制,在实际的项目开发过程中是不能简单地使用以上代码,还是要通过完善的try机制来识别异常并能够保证系统的稳定运行以及异常中的自恢复。

最后的最后,祝自己生日快乐~~~~~~~~~~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值