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

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

1.snap7安装

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

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

snap7读写西门子plc1200步骤(python)_第1张图片

截图是我已经安装过了,如果有问题,请检查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 
    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安装文件夹。资源处有。

snap7读写西门子plc1200步骤(python)_第2张图片

 

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

在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)。

snap7读写西门子plc1200步骤(python)_第3张图片

(2)打开保护,修改为无保护,默认无保护。snap7读写西门子plc1200步骤(python)_第4张图片

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

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

点到项目树的DB1右击打开属性列表,保护为无保护。snap7读写西门子plc1200步骤(python)_第5张图片

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

snap7读写西门子plc1200步骤(python)_第6张图片

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

snap7读写西门子plc1200步骤(python)_第7张图片

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

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

snap7读写西门子plc1200步骤(python)_第8张图片

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

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自带地址分类,如下:

snap7读写西门子plc1200步骤(python)_第9张图片

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。

snap7读写西门子plc1200步骤(python)_第10张图片

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

下面是我读写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也完成该界面操作。

 

你可能感兴趣的:(python,PLC,Linux)