2020年02月17日更新:为了更加方便快捷地提供西门子S7 Ethernet系列(S7 200smart 、300、400、1200、1500等系列)PLC数据交换到工业云平台(WebAPP或移动端APP),作者开发了KepOPC系列PLC驱动之一的S7中间件,具体功能描述及应用介绍参照站内博文 https://blog.csdn.net/weixin_29482793/article/details/104220789
感兴趣的朋友可以访问www.kepopc.com了解,同时欢迎关注作者博客和微信公众号“KepOPC工业互联”了解更多产品资讯。
2020.02.17本站提供试用下载网盘地址:https://pan.baidu.com/s/1ypQEgDtBwa0Gre7UsVqGvA 提取码:rfvn
S7应用视频介绍 https://mp.weixin.qq.com/s/2BBhpMKuTC090FPc-r1bfQ
----------------------------------------------------------------------------------------------------------------------------------------
最近要开发基于TCP/IP协议的PC上位机和西门子S7系列PLC的通讯和数据采集,网上搜罗了一圈发现有python snap7这个工具,鉴于此次开发时间有限,就自己研究上手了,期间也碰到很多安装和连接、读取数据的问题,网上解决方案有限,现提供一个测试版本,该版本有如下功能:
2018-03-14 更新python s7-1200测试版程序技术特性:
1、PC直接通过TCP网口连接S7-1200系列PLC;
2、按照PLC导出的点表地址获取I、Q、M区的地址和类型进行读取;
3、读出的值下一步可以通过MYSQL或socket的方式记录和推送;
4、目前是按照每个点逐个读取,因此效率较低,后续考虑按块读取,那样效率就很高了,基本上读一次时间控制在ms级别;
5、摆脱了OPC的束缚,之前都需要从OPC中转一下,这下PC可以直接通过网络连接PLC。
(python s7-1200测试版本打包程序)下载地址:https://pan.baidu.com/s/1cRK9vIxW4T1_sVFieUESjA
感谢(蔽月八云):https://www.jianshu.com/p/5284de40a139 的总结和分析,因为我也是个PLC小白,python snap7的优势就在于,一个PLC小白也能很快地利用python和PLC建立通讯,并获取寄存器的值,这些值为我们的数据分析提供了数据基础,基于TCP/IP方式的通讯,是它最大的优势,期间也用过modbus TCP的方式读取,但是40001和M区的对应地址关系把我搞的头晕,相比而言modbus简单更易操作,python snap7更加专业。
另附 python snap7安装常见问题和步骤:https://stackoverflow.com/questions/33697263/python-snap7-windows-cant-find-snap7-library
2018年07月31日更新:
感谢每一位关注的朋友,由于最近真的很多人问我python snap7,所以还是觉得应该分享一下微薄的经验,snap7的read_area方法和Kepserver读西门子TCP/IP Ethernet驱动的读取方法是一样的,我也是利用网络抓包工具比对着消息体格式才找到功能码、地址、类型、长度的对应关系,确实还是因为相关的介绍太少,虽说KepOPC也能更加容易实现这些功能,但是我仍坚信snap7才是最美解决方案。(下面的文字适合已经连上PLC的朋友):
1、利用def read_area(self, area, dbnumber, start, size)函数读I\Q\M区不同类型寄存器的值:
for i in range(0,len(read_list)):
tag_id = read_list[i]['id']
tag_type = read_list[i]['type']
plc_readtime = time.strftime('%Y-%m-%d %H:%M:%S')
if tag_id[0]=='I' and tag_type=='Boolean'or tag_type=='Bool':
result = client.read_area(0x81, 0, int(tag_id[1]), 1)
for j in range(0,8):
if (int(struct.unpack('!B', result)[0]) & pow(2,j)!=0):
i_temp_value=1
else:
i_temp_value=0
elif tag_id[0]=='Q' and tag_type=='Boolean'or tag_type=='Bool':
result = client.read_area(0x82, 0, int(tag_id[1]), 1)
q_query_str = ''
for j in range(0,8):
if (int(struct.unpack('!B', result)[0]) & pow(2,j)!=0):
q_temp_value=1
else:
q_temp_value=0
elif tag_id[0]=='M':
if tag_id[1]!='B' and tag_id[1]!='D'and tag_type=='Boolean'or tag_type=='Bool':
m_id_res = re.findall(r'M(\d+)',tag_id)
result = client.read_area(0x83, 0, int(m_id_res[0]), 1)
for j in range(0,8):
if (int(struct.unpack('!B', result)[0]) & pow(2,j)!=0):
m_temp_value=1
else:
m_temp_value=0
elif tag_id[1]=='B'and tag_type=='Byte'or tag_type=='Boolean':
mb_query_str = ''
result = client.read_area(0x83, 0, int(tag_id[2:]), 1)
read_list[i]['value']=struct.unpack('!B', result)[0]
elif tag_id[1]=='D'and tag_type=='DWord':
md_query_str = ''
result = client.read_area(0x83, 0, int(tag_id[2:]), 4)
read_list[i]['value']=struct.unpack('!L', result)[0]
else:
print "tag_id !=MB\MD\M,or type error!"
else:
pass
以上红色的文字为主要读取代码,用于按照I/M/Q区+地址+类型的寄存器值的读取,读取完需要利用struct.unpack方法转换成我们要的值。
2、利用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。
2019年12月26日更新:1、新增对S7 200smart的连接;2、新增连接号定义;3、新增V区(V\VB\VW\VD)的读写值。
3、SiemensTCPIP测试工具的使用和下载方法:
(1)下载测试工具 SiemensTCPIP.exe
下载地址:https://pan.baidu.com/s/18JgupJKUcM7qCHNHhes87A
(2)程序运行
运行前请将snap7.dll和snap7.lib拷贝到你的操作系统对应的版本的System32或SysWOW64下。
(3)程序运行
备注: 不同PLC的CPU机架号、插槽号和功能码0x81,0x82,0x83及值类型长度如下表:
公众号往期文章回顾:
智能制造还有多远,KepOPC又能解决哪些问题呢?
S7中间件如何通过MySQL与PLC读写交互?
西门子S7系列PLC数据采集及交换平台功能介绍
西门子S7系列PLC数据采集及交换平台使用说明
KepOPC工业互联网数据交换平台
OPC实时数据发布到MQTT及存储MySQL关系数据库
OPC实时数据发布到MQTT及存储IfluxDB时序数据库
KepOPC不止是OPC客户端那么简单
如何利用Socket和COM通迅实现非标协议设备的工业互联?