snap7读写西门子plc1200步骤(python) PLC通讯

8 篇文章 11 订阅

本文是利用snap7进行对plc1200进行读写,所用语言是python3,windows7下,plc具体型号为S7-1212DC/DC/DC  

注意在ubuntu安装的时候,先安装python3-pip在进行pip3 install,否则默认使用python2环境。

1.snap7安装

 win+R打开运行串口,输入cmd,确定后,输入下面的命令:(需要提前安装python 和 pip)

使用python的pip命令安装即可:pip install python-snap7

截图是我已经安装过了,如果有问题,请检查python安装是够正确,是否增加python的路径到环境变量中。

snap7相关内容可以查看链接https://blog.csdn.net/Paul22101574/article/details/81583198

不做深入探究,请继续向下看。

******************************************************************************************

windows安装报错:

Traceback (most recent call last):
  File "Y:\Lonnox\Projekte\Bibliothek\Python und SPS\S7-1200 Test.py", line 6, in <module>
    plc = snap7.client.Client()
  File "C:\Python34\lib\site-packages\snap7\client.py", line 30, in __init__
    self.library = load_library()
  File "C:\Python34\lib\site-packages\snap7\common.py", line 54, in load_library
    return Snap7Library(lib_location).cdll
  File "C:\Python34\lib\site-packages\snap7\common.py", line 46, in __init__
    raise Snap7Exception(msg)
snap7.snap7exceptions.Snap7Exception: can't find snap7 library. If installed, try running ldconfig

解决方法:将dll lib文件拷入python安装文件夹。资源处有。

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

2021.3.1更新

如果在linux出现同样的报错,解决方法如下:

https://www.cnblogs.com/yinsedeyinse/p/13657904.html

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

******************************************************************************************

在ubantu14.04中linux系统安装及配置

系统自带python2,同样的pip install python-snap7,安装snap7库成功。

下面配置系统的ip地址:

1.确保ubantu关闭了防火墙

 启用

 sudo ufw enable
 sudo ufw default deny 
作用:开启了防火墙并随系统启动同时关闭所有外部对本机的访问(本机访问外部正常)。

关闭

sudo ufw disable

 查看防火墙状态

 sudo ufw status 

2.配置eth0或者eth1 的静态ip地址

$gedit /etc/network/interfaces

# interfaces eth0 for  snap7 connect plc
auto eth0
iface eth0 inet static
address 192.168.0.100
netmask 255.255.255.0
gateway 192.168.0.1

保存,重启。

ifconfig就可以看见修改了。
 

 

 

2.设置西门子PLC

使用博图软件对PLC属性进行设置

(1)打开plc,更改IP地址:(注意这一步不是必须的,我自己链接的时候使用默认192.168.0.1总是出现连接超时或者失败,修改了IP就好了,修改为192.168.1.11)。

(2)打开保护,修改为无保护,默认无保护。

(3)数据读写可以对输入(I)、输出(Q)、M区甚至是T区(时钟)区读写,但是实际操作中,我对I区读写没有任何反应,对M区和Q区测试可以,所以建议使用全局DB数据块进行读写,然后PLC程序稍加修改就行。例如,原来的I0.1可以使用M10.1的数字使用==指令判别,==1接通,逻辑差不多,就是需要把I区的开关转换成M区。

好了,废话到此。建立全局数据块DB_1,这里的DB号为1.

点到项目树的DB1右击打开属性列表,保护为无保护。

取消优化的块访问,默认块访问是优化的

好了,看下DB块中的数据吧。

我这里只用了这几个,重要的是看数据块的偏移量,这里是后面要用到的地址。

暂停,请打开网址,端好小板凳,认真观看  http://www.ad.siemens.com.cn/service/elearning/Course/455.html

这三个视频。如果想怎加记忆,每个视屏同名的会有强化记忆的小程序。

PLC的部分到此结束,请给PLC接上24V电源,用网线把电脑和PLC连接,把刚才修改plc的项目导入plc中。如果连不上,可以手动修改电脑的ip为192.168.1.0,和之前设置的plc需要在同一个子网下面。

下面打开python的shell,确认是否能够连接和读写。

输入下面的命令

>>> import snap7
>>> plc=snap7.client.Client()
>>> plc.connect('192.168.1.11',0,1)

这里需要注意的是ip和你设置的Plc的ip一致,connect的参数,0,1位一般为默认参数,是指代plc的网口插槽位置的。断开连接直接调用plc.disconnect()就可以断开连接了。

下面介绍两个最最重要的函数:也就基本上只使用到这些:

read_area(area,dbnumber,start,size)

write(area,dbnumber,start,data)

首先介绍第一个参数,我们读写,主要的区别就是地址不同,plc自带地址分类,如下:

0x81是输入区,0x82输出区,0x84是db块。

第二个参数是dbnumber,输入输出区域默认为0,db块就是块的序号,我这里是数据块_1,其实就是1号,所以写1.

下面两个参数,start和size,对于I0.3起始地址为0,对应size为3

对于M3.4,对应的就是M(0x83),起始地址是3,对应bit位是4,

用write_area(self, area, dbnumber, start, data):函数写I\Q\M区不同类型寄存器的值:

      过程与read_area相逆,根据地址和数据类型,把值填到函数的data中。

      举个写的例子:client.write_area(0x82, 0,0,struct.pack('B',24)) 意思是向PLC的开关量输出口D0.3和D0.4值写1,24的二进制是00011000。

这里需要提醒下,因为读写获得的都是16进制的数字,需要把相对应的解码和编码到10进制方便读写。

>>> plc.write_area(0x84,1,0,struct.pack('B',1))
>>> data=plc.read_area(0x84,1,0,8)
>>> print(data)
bytearray(b'\x01\x00\x00\x00\x00\x00\x00\x00')

这是对db块的M1.0写1,读写例子,。读取时候为了减少多次读取,我是用了一次性读取了8位。

这里给出我记录的某一博文的例子,有错误不管,哈哈哈

---------------------------------------------------------------老子是分割线--------------------------------------------------------------------------

通过读写PLC的M10.1、MW201来具体看看如何读写PLC。

import struct

import time

import snap7

def plc_connect(ip, rack=0, slot=1):

"""

连接初始化

:param ip:

:param rack: 通常为0

:param slot: 根据plc安装,一般为0或1

:return:

"""

client = snap7.client.Client()

client.connect(ip, rack, slot)

return client

def plc_con_close(client):

"""

连接关闭

:param client:

:return:

"""

client.disconnect()

def test_mk10_1(client):

"""

测试M10.1

:return:

"""

area = snap7.snap7types.areas.MK

dbnumber = 0

amount = 1

start = 10

print(u'初始值')

mk_data = client.read_area(area, dbnumber, start, amount)

print(struct.unpack('!c', mk_data))

print(u'置1')

client.write_area(area, dbnumber, start, b'')

print(u'当前值')

mk_cur = client.read_area(area, dbnumber, start, amount)

print(struct.unpack('!c', mk_cur))

def test_mk_w201(client):

"""

测试MW201,数据类型为word

:param client:

:return:

"""

area = snap7.snap7types.areas.MK

dbnumber = 0

amount = 2

start = 201

print(u'初始值')

mk_data = client.read_area(area, dbnumber, start, amount)

print(struct.unpack('!h', mk_data))

print(u'置12')

client.write_area(area, dbnumber, start, b'')

print(u'当前值')

mk_cur = client.read_area(area, dbnumber, start, amount)

print(struct.unpack('!h', mk_cur))

time.sleep(3)

print(u'置3')

client.write_area(area, dbnumber, start, b'')

print(u'当前值')

mk_cur = client.read_area(area, dbnumber, start, amount)

print(struct.unpack('!h', mk_cur))

if __name__ == "__main__":

client_fd = plc_connect('192.168.0.1')

test_mk10_1(client_fd)

test_mk10_1(client_fd)

plc_con_close(client_fd)

从代码可见,MW201,根据M确定area为MK,根据W确定数据amount为2Btye,根据201确定start为201,读出来的数据根据数据长度用struct进行unpack,写数据对应strcut的pack。

这里给出PLC变量类型和大小,这样对应确定读写的amount。

如何使用 Python 构建 PC 通信?

---------------------------------------------------------------老子是分割线--------------------------------------------------------------------------

下面是我读写i0.1的例子,可是却没有成功,原因未知。

>>> plc.write_area(0x81,0,0,struct.pack('B',1))
>>> data=plc.read_area(0x81,0,0,1)
>>> print(data)
bytearray(b'\x00')
>>> data=plc.read_area(0x81,0,0,8)
>>> print(data)
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')

下面这个同样的,不过使用了转码,以供转码的示范

>>> plc.write_area(0x81,0,0,struct.pack('B',1))
>>> data=plc.read_area(0x81,0,0,1)
>>> print(struct.unpack('!B',data)[0])
0
>>> data=plc.read_area(0x81,0,0,0)

特别提醒,对于DB块M的读写时,当是多个字时,低地址的字节其实在写入时候位于数字的高字节段,也就是高位,高地址的字节反而位于数字的低位数段。所谓的大端模式和小端模式,请自行百度。知道就行。

写数据都是8位一次写入,如果写入MW类型或者Real等更大数据,需要8位分割,我的实现是每次进行位与操作,然后通过移位8位获得高位。

 

在提供几篇不错的博客::

https://blog.csdn.net/xiaoxianerqq/article/details/81661010

https://blog.csdn.net/weixin_29482793/article/details/79555836

第二个博客博主做了个软件,如果大家只是玩一下,可以看看,但是源码没有开放,可以用QT也完成该界面操作。

***************************************************************************更新 2020.12.15 WJ*************************************************************

如上文所示,存在字节大小端问题,所以每次读写的时候需要去编解码,转换,很费事。

偶然尝试用可变字节数组bytearray获得新的方法

import snap7
plc=snap7.client.Client()
plc.connect('192.168.1.11',0,1)

#DB1中偏移2位置写入两个字节
plc.write_area(0x84,1,2,b'\x12\x34')

##DB1中偏移6位置写入四个字节
plc..write_area(0x84,1,6,b'\x12\x34\x56\x78')

#读取
first=plc.read_area(0x84,1,2,2)
second=plc.read_area(0x84,1,6,4)

#这里可以打印出来不过都会视为字符串等
#我需要将其转换成整数
data1=int.from_bytes(first,'big')
#需要注意这里会视为无符号的整形数据
#如果存在符号,可以使用减法去计算超过你最大正整数时的复数数据

#例如

data2=int.from_bytes(second,'big')-0xFFFFFFFF-1

 

 

 

 

 

 

 

 

  • 26
    点赞
  • 200
    收藏
    觉得还不错? 一键收藏
  • 36
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值