踩坑实录:Python对西门⼦PLC(S7-200_SMART)寄存器的读写(VB区)2020.11.09更新VD和VW区读写代码
问题描述
⽹上有很多关于如何⽤Python读写plc的I、Q、M、DB区的⽂章和代码,但是如果实践中需要⽤到V区,那些⽂章将不太可⾏。
他们的⽅法都是使⽤def read_area(self, area, dbnumber, start, size)和write_area(self, area, dbnumber, start, data):函数读写
I\Q\M区不同类型寄存器的值,但是如果我们想读写VB区的值呢?
解决办法
据测试,VB区即为DB寄存器中的B区(就是在DB区以⼀个字节为单位进⾏读取),即V区即为DB区
在snap7中的源码关于寄存器的描述:
def db_read(self, db_number, start, size):
"""This is a lean function of Cli_ReadArea() to read PLC DB.
:returns: user buffer.
"""
logger.debug("db_read, db_number:%s, start:%s, size:%s"%
(db_number, start, size))
type_ = snap7.snap7types.wordlen_to_ctypes[snap7.snap7types.S7WLByte]
data =(type_ * size)()
result =(self.library.Cli_DBRead(
self.pointer, db_number, start, size,
byref(data)))
check_error(result, context="client")
return bytearray(data)
@error_wrap
def db_write(self, db_number, start, data):
"""
Writes to a DB object.
:param start: write offset
:param data: bytearray
"""
wordlen = snap7.snap7types.S7WLByte
type_ = snap7.snap7types.wordlen_to_ctypes[wordlen]
size =len(data)
cdata =(type_ * size).from_buffer_copy(data)
logger.debug("db_write db_number:%s start:%s size:%s data:%s"%
(db_number, start, size, data))
return self.library.Cli_DBWrite(self.pointer, db_number, start, size,
byref(cdata))
经过测试,db_number和size这两个参数只能设置为1可⾏,设置为其他会报错,因此在之后调⽤的时候,直接把这两个参数赋值1。
因为在写⼊时,对data的格式有要求,因此写了⼀个函数把原函数封装了起来:
def read_VB(client, offset):
""" :param client: client
:param offset: int
:returns: str.
"""
vb_data = client.db_read(1, offset,1)
return vb_data[0]
def write_VB(client, offset, data):
""" :param client: client
:param offset: int
:param data: str
"""
data =int(data)
temp =hex(int(data))[2:]
if data <0or data >255:
print("请输⼊0-255之间的数")
else:
if data <16:
temp ="0"+ temp
client.db_write(1, offset,bytes.fromhex(temp))
print("向寄存器VB"+str(offset)+"写⼊"+str(data)+"成功")
在连接plc之后直接调⽤即可。
整体代码:
import struct
import time
import snap7
def plc_connect(ip,type, rack=0, slot=1):
"""
连接初始化
:param ip:
:param type::param connection_type: 1 for PG, 2 for OP, 3 to 10 for S7 Basic :param rack: 通常为0
:param slot: 根据plc安装,⼀般为0或1
:return:client
"""
client = snap7.client.Client()
client.set_connection_type(type)
return client
def plc_con_close(client):
"""
连接关闭
:param client:
:return:
"""
client.disconnect()
def read_VB(client, offset):
""" :param client: client
:param offset: int
:
returns: str.
"""
vb_data = client.db_read(1, offset,1)
return vb_data[0]
def write_VB(client, offset, data):
""" :param client: client
:param offset: int
:param data: str
"""
data =int(data)
temp =hex(int(data))[2:]
if data <0or data >255:
print("请输⼊0-255之间的数")
else:
if data <16:
temp ="0"+ temp
client.db_write(1, offset,bytes.fromhex(temp))
print("向寄存器VB"+str(offset)+"写⼊"+str(data)+"成功")
if __name__ =="__main__":
client_fd = plc_connect('192.168.2.1',2)
print("connect success")
write_VB(client_fd,1,"16")
data = read_VB(client_fd,1)
print(data)
plc_con_close(client_fd)
运⾏结果:
python和vb的代码可以通用吗
def write_VD(client, offset, data):
temp =hex(int(data))
temp = temp[2:].zfill(8)
# print(type(temp))
try:
client.write_area(snap7.snap7types.areas.DB,1, offset,bytes.fromhex(temp)) print("向寄存器VB"+str(offset)+"写⼊"+str(data)+"成功")
except Exception as e:
time.sleep(0.003)
write_VD(client, offset, data)
def read_VD(client, offset):
"""This is a lean function of Cli_ReadArea() to read PLC DB.
:param client: client
:param offset
:returns: data int.
"""
try:
v_data = ad_area(snap7.snap7types.areas.DB,1, offset,4)
data =int.from_bytes(v_data, byteorder='big', signed=False)
except Exception as e:
time.sleep(0.003)
data = read_VD(client, offset)
return data
def write_VW(client, offset, data):
temp =hex(int(data))
temp = temp[2:].zfill(4)
# print(type(temp))
try:
client.write_area(snap7.snap7types.areas.DB,1, offset,bytes.fromhex(temp)) print("向寄存器VB"+str(offset)+"写⼊"+str(data)+"成功")
except Exception as e:
time.sleep(0.003)
write_VW(client, offset, data)
def read_VW(client, offset):
"""This is a lean function of Cli_ReadArea() to read PLC DB.
:param client: client
:param offset
:returns: data int.
"""
try:
v_data = ad_area(snap7.snap7types.areas.DB,1, offset,2)
data =int.from_bytes(v_data, byteorder='big', signed=False)
except Exception as e:
time.sleep(0.003)
data = read_VW(client, offset)
return data
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论