首页 > 编程知识 正文

android开发笔记,开发笔记

时间:2023-05-06 17:10:26 阅读:188112 作者:3804

开发笔记1.0 如何通过python与西门子1500plc进行通讯anaconda与snap7的安装snap7库使用详解read_area()地址信息:DB块地址:字节地址:字节长度: 示例如下: write_area()读字节:修改位数据:写入修改后的数据: 扩展内容

如何通过python与西门子1500plc进行通讯

入行自动化小半年,因为有图像处理和plc控制两方面协调的需求,而笔者之前主用python,因此对此进行了一段时间的探索,也走了很多弯路,写个笔记给自己也给后来者。

anaconda与snap7的安装

在寻找可用的通讯模块这方面,笔者陆陆续续试了很多,最后还是选择了snap7,如果有更方便的模块,欢迎讨论。
开发环境的配置是老生常谈了,相关博客非常多,不再赘述,只说几点需要注意的事项:

首先,snap7的安装,我不是太清楚怎么修改anaconda的库源,反正使用pip可以安装snap7,但是使用conda就找不到,解决方法是使用anaconda自带的Anaconda Prompt输入:

pip install python-snap7

注意python字段不要落下

其次,snap7安装结束后需要把snap7-full-1.4.2releaseWindowsWin64目录下的dll文件和lib文件放至Anaconda的安装目录和系统windows下的SysWOW64下。

snap7库使用详解

这一步踩了很多坑,我也不是想针对某些博客,但是很多人压根就没有实验过代码,把别人的复制一遍就成了一篇技术博客,断章取义,以讹传讹,对后来者造成了很大的麻烦。
本段只说方法,由于项目特殊性,不便截图。
开门见山:

import snap7my_plc = snap7.client.Client()my_plc.connect('192.168.0.10',0,1)#IP地址,第二个数字非0即1,第三个数字是cpu的机架号,请去plc控制柜查看

三句话建立对象,之后我们就可以使用read_area与write_area对plc内存数据进行读写,实现通讯。

在进行以下工作之前,必须着重强调一点:基于python的snap7只能对内存里整段的字节进行读写,而不可以直接操作具体的位。

read_area()

示例:

i_pre = my_plc.read_area(129,0,20,1)

四个参数分别代表地址信息,DB块地址,字节地址,字节长度

地址信息:

129 – I区,130 – Q区,131–M区,132–DB块,目前主要用的是这四块。

DB块地址:

对于IQM区,该数字为0,对于db块,该数字为db块的地址。

字节地址:

整数字节起始地址。

字节长度:

指向后读取的字节长度,一般针对位读取的话,填1即可,针对整数字节int32或int64等,需要酌情增加。

示例如下: i_pre = my_plc.read_area(129,0,20,1)#表示I20.0为起点,向后读取1个字节q_pre = my_plc.read_area(130,0,20,2)#表示Q20.0为起点,向后读取2个字节m_pre = my_plc.read_area(131,0,20,3)#表示M20.0为起点,向后读取3个字节db_pre = my_plc.read_area(132,20,2,1)#表示DB20为起点,地址偏移量为2,向后读取1个字节

通过字节读取之后的数据需要进行转换,转换之后会得到一个数组,拿出数组内相应的数字就是能够被处理的8位整数:

import structi = struct.unpack('!B',i_pre)[0]

再通过字节位读取得到我们想要的开关量,笔者并没有找到字节位读取相关的模块,所以采用以下方法:
右移–取模

#输入字节和地址偏移量def read_bit(num,bit): out = num>>bit if out%2 == 0: return False else : return True

如果有更方便的做法,欢迎讨论
至此,read_area()模块用法的坑几乎都填上了,基于以上流程,可以完成I、Q、M、BD区所有数据的字节读取与位读取及其相关函数编写。

write_area()

write_area()模块要比read_area()模块复杂些,由于python-snap7无法对位进行操作,因此int数据的写相对容易,而位数据写的操作就必须遵循以下流程:读字节–修改位数据–写字节

首先我们先理解write_area()函数的参数含义,示例:

my_plc.write_area(129,0,20,out_pre)

四个参数分别代表地址信息、DB地址、字节地址、写入数据
前三个参数同read_area(),写入数据则是打包后的字节数据。

在对write_area()模块参数了解后,我们继续完善开关量写入数据的全部流程:

读字节:

没啥好说的,利用前文的read_area()模块读取字节数据并使用unpack方法获得整数数据

修改位数据:

拿到8位整数之后,我们需要对其中的某个位进行修改而不改变其余字节的数据,笔者依旧是没找到相应的模块,采用的以下方法:

#输入字节数据,需要修改的位地址,需要修改的位参数,输出修改后的字节数据def write_int(num,bit,boolnum): out = num>>bit if boolnum == False: if out%2 ==0: return num else: return num - 2**bit else: if out%2 ==0: return num + 2**bit else: return num

如果有更加方便的做法,欢迎讨论

写入修改后的数据:

拿到修改后的数据,采用pack()方法将数据打包再发回plc:

out_pre = struct.pack('!B',byte_num)my_plc.write_area(131,0,20,out_pre)

以上就是位数据写入的流程,如果是整数数据的话,只需要进行第三步即可,如果是好几个字节的数据,那就依次右移8位,依次写入

扩展内容

主要模块read_area()和write_area()掌握之后,就可以对plc内存区进行读写。
此外,笔者在开发期间,遇到了负数的传输,plc里负数按照补码存储,在传输之前需要对数据进行补码计算。
笔者经验尚浅,所有内容均为自学,若有错漏,还请各位小伙伴们及时提醒。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。