新手使用Python读取西门子1200PLC数据
不足还请大佬们指正,少骂我!
首先,对于PLC内需要允许外部连接
对于代码,我是使用Pcpycharm做的,对于连接西门子1200、1500系列,需要安装snap7功能包
pip install python-snap7
安装完成后看见successful字样就说明安装好了
导入模块
import snap7
正常代码:
IP=self.lineEdit.text()#获取IP地址
print(IP)#我这里做的GUI界面,界面输入IP地址
PLCBrand=self.comboBox.currentText()#获取选择的品牌 界面选择PLC品牌
print(PLCBrand)
if PLCBrand=="西门子":#选择品牌位西门子
Plc = snap7.client.Client()#建立客户端
if plcconnect:#连接标志位 当已连接 再次执行就断开了
Plc.disconnect()#断开连接
plcconnect = False
self.label_3.setText("未连接")
self.timer.stop()
else:#若是未连接
Plc.connect(str(IP), 0, 1)#进行PLC链接
#连接
# 连接s7 - 1200 / 1500系列
#:paramip: PLC / 设备IPV4地址
#:paramrack: 服务器上的机架
#:paramslot: 服务器上的插槽
plcconnect=Plc.get_connected()#连接后的标志状态 已连接为True 未连接为False
self.label_3.setText("已连接")
当通过上面代码连接OK后就可以读写数据了
读写数据的方式有多种,不过最常用的还是下方我是用的这种,都是搜了好多案例的
# areas = ADict({
# 'PE': 0x81, #input 输入区
# 'PA': 0x82, #output 输出区
# 'MK': 0x83, #bit memory 中间存储区(M区)
# 'DB': 0x84, #DB区
# 'CT': 0x1C, #counters
# 'TM': 0x1D, #Timers
# })
#上方这一块叫啥玩意我也不知道,反正就是这样用,是划分读写西门子各种数据区域的
if plcconnect:#如果已连接
DB=1#DB块号为1 若不是读取DB块,此值为0
Statebyte=36 #要读取的字节开始地址 **记住 是字节**
Numbyte=8#要读取的字节数量
Data = Plc.read_area(Areas.DB, DB, Statebyte, Numbyte)
#读取的数据 此前定义的客户端.read_area(读取区域,DB块值,读取开始字节,读取的字节数量)
#关读取区域,我看有的认识直接填0X84十六进制代码,但是我这里实际试了一下是不行的,需要填Areas.DB这种,具体的可以再自己电脑上看一下read_area提示来决定读取区域填什么。
#Data读取的数据是以字节为单位划分的,然后以十六进制表示的,高低位是反着的
#i = struct.unpack('!B', Data)[0]
# i = struct.unpack('!B', Data)[1]
print("数据为", Data)#看下图读取内容
t=snap7.util.get_dword(Data,0)
#snap7.util.get_dword(数据源,数据源内读取的开始字节位置)
#snap7.util.get_dword 这里叫啥我也不知道,反正输入snap7.util. 就提示了
#我这里是从36字节开始读取8个字节,因为我设置的是Dword数据,占用8字节
print(t)
#然后就直接将8个字节解析为十进制数据了
这里Data显示的十六进制我也不知道为啥,就是有时候显示的有问题,但实际是对的(大概率是我没搞懂)
t=snap7.util.get_bool
这个是读取BOOL量
以下是读取的输出地址
DB=0
Statebyte=0
Numbyte=2
Data = Plc.read_area(Areas.PA, DB, Statebyte, Numbyte)
#i = struct.unpack('!B', Data)[0]
# i = struct.unpack('!B', Data)[1]
#print("数据为", Data)
#t=snap7.util.get_dword(Data,0)
#print(t)
#Data = Plc.read_area(Areas.PE, 0, 0, 1)
for i in range(Statebyte,Statebyte+Numbyte):
#print("i=",i)
for a in range(0,8):
#print("a=",a)
t=snap7.util.get_bool(Data,i-Statebyte,a)
print("I ",str(i),'.',str(a),t)
这是读取的输出地址 应该是Q,不是I