最近偶尔在网上看到可以用Python通过snap7与PLC建立连接并读写数据,好多小伙伴没有现成的PLC,这里介绍一个电脑模拟PLC与python通讯。效果与实际情况一样的。这里是以SIEMENS的PLC为例,通过Pycharm与TIA V17建立连接,对其DB块、M区、Q区、I区读写数据。后面还添加了200系列V区的读写数据。请注意在程序中个别只对200专用!200系列的PLC不能模拟,也就不能用那个通讯工具了,直接与PLC通讯就好了。
1、在下载的1.4.2文件夹中找到文件
2、将这两个文件拷贝到python的安装目录include中
3、cmd中输入 pip install python-snap7,打开pycharm查看snap7是否安装成功,然后导入snap7包
按照参考链接打开TIA V17仿真,建立好变量连接在线:
4、以管理员身份打开NetToPLCsim软件,如果102端口被占用,会提示重新获取102端口,在弹窗里点击【是】。
等待端口修改成功。
点击【Add】,填写电脑和PLC设备的IP地址,电脑和PLC设备的IP地址最好一样。
填写完毕后点击【Start Server】。
运行程序就可以测试是否可以读取PLC中数据和写入PLC数据,以下是测试代码,在参考文章中读写都是用区域代码,但是实际测试无法匹配到区域代码。还有读写DB块和M区、Q区、I区的方法稍有不同需要注意。
import snap7
from snap7.util import *
plc = snap7.client.Client()
plc.set_connection_type(3) # (200专用)
# 定义Plc连接
def plc_connect(ip, rack, slot):
plc.connect(ip, rack, slot)
if plc.get_connected():
print("连接成功")
# PLC断开连接
def plc_disconnect():
plc.disconnect()
def dbRead(dbnum, dblength):
"""
DB块的读操作;如果是200smart系列的将dbnum设置为0
:param dbnum:
:param dblength:
:return:
"""
data = plc.read_area(snap7.types.Areas.DB, dbnum, 0, dblength)
print(get_int(data, 0))
print(get_bool(data, 2, 0))
print(get_dword(data, 4))
print(get_real(data, 8))
print(get_bool(data, 0, 0))
print(get_byte(data, 2))
def dbWrite(dbnum, dblength):
"""
DB块的写操作;如果是200smart系列的将dbnum设置为0
:param dbnum: DB块的序号
:param dblength:
:return: 字节长度,根据需要设定
"""
data = plc.read_area(snap7.types.Areas.DB, dbnum, 0, dblength)
# set_int(data, 0, 20)
# set_bool(data, 2, 0, False)
# set_dword(data, 4, 1000)
# set_real(data, 8, 11.3)
# set_int(data, 12, 99)
set_bool(data, 0, 0, False) # 设置DBD0.DBX0.0为False
# set_byte(data, 2, 2)
# set_int(data, 4, 100)
plc.write_area(snap7.types.Areas.DB, dbnum, 0, data)
print('写入成功!!!')
def mRead1(num, bit):
"""
M区的读操作--------bool
:param num:
:param bit:
:return:
"""
data = plc.read_area(snap7.types.Areas.MK, 0, num, 1)
print(get_bool(data, 0, bit))
def mRead2(num):
"""
M区的读操作--------int/word/dint/dword
:param num:
:return:
"""
data = plc.read_area(snap7.types.Areas.MK, 0, num, 2)
print(get_int(data, 0)) # 读取MW0值
print(get_byte(data, 0)) # 读取MB0值
print(get_dint(data, 0)) # 读取MD0值
def mWrite1(byte, bit, value):
"""
M块的写操作---------bool
:param byte:
:param bit:
:param value:
:return:
"""
data = plc.read_area(snap7.types.Areas.MK, 0, byte, 1)
set_bool(data, 0, bit, value)
plc.write_area(snap7.types.Areas.MK, 0, byte, data)
def mWrite2(byte, value):
"""
M块的写操作---------int/word/dint/dword
:param byte:
:param value:
:return:
"""
data = plc.read_area(snap7.types.Areas.MK, 0, byte, 4)
# set_int(data, 0, value)
set_dint(data, 0, value)
plc.write_area(snap7.types.Areas.MK, 0, byte, data)
def qRead1(byte, bit):
"""
Q区的读操作-------------bool
:param byte:
:param bit:
:return:
"""
data = plc.read_area(snap7.types.Areas.PA, 0, byte, 1)
print(get_bool(data, 0, bit))
def qRead2(byte):
"""
Q区的读操作-------------byte/int/word/dint/dword
:param byte:
:return:
"""
data = plc.read_area(snap7.types.Areas.PA, 0, byte, 2)
# print(get_byte(data, 0))
print(get_int(data, 0))
# print(get_dint(data, 0))
def qWrite1(byte, bit, value):
"""
Q区的写操作----------bool
:param byte:
:param bit:
:param value:
:return:
"""
data = plc.read_area(snap7.types.Areas.PA, 0, byte, 1) # read_area的SIZE参数,这里默认位一个字节
set_bool(data, 0, bit, value)
plc.write_area(snap7.types.Areas.PA, 0, byte, data)
def qWrite2(byte, value):
"""
Q区的写操作----------int/word/dint/dword
:param byte:
:param value:
:return:
"""
data = plc.read_area(snap7.types.Areas.PA, 0, byte, 2) # read_area的SIZE参数,int-2;dint-4
set_int(data, 0, value) # 读取QW0值
# set_dint(data, 0, value)
plc.write_area(snap7.types.Areas.PA, 0, byte, data)
def iRead1(byte, bit):
"""
输入映象区的读操作-------bool
:param byte:
:param bit:
:return:
"""
data = plc.read_area(snap7.types.Areas.PE, 0, byte, 1) # Size参数,这里我们定义为1个字节的长度
print(get_bool(data, 0, bit))
def iRead2(byte):
"""
输入映象区的读操作-------byte/int/word/dint/dword
:param byte:
:return:
"""
data = plc.read_area(snap7.types.Areas.PE, 0, byte, 2) # Size参数,这里我们定义为1个字节的长度
# print(get_byte(data, 0))
print(get_int(data, 0))
# print(get_dint(data, 0))
if __name__ == '__main__':
plc_connect('192.168.1.10', 0, 1)
dbRead(1, 4)
dbWrite(1, 4)
mRead1(20, 2)
mRead2(100)
mWrite1(20, 6, True)
mWrite2(22, 100)
qRead1(100, 5)
qRead2(200)
qWrite1(100, 5)
iRead1(99, 7)
iRead2(122)
plc_disconnect()
TIA V17 链接:https://pan.baidu.com/s/1vfzzDhqKLy49pl9V0AINsA 提取码:hmn8
西门子PLC连接工具 ,NetToPLCsim;NetToPLCSim download | SourceForge.net
Snap7 链接: https://pan.baidu.com/s/1--Zhwj1gs417rpLrpV1QKQ 提取码: qtnm
参考:通讯测试工具和博图仿真机的连接教程
Python读写PLC