python通过S7协议读取西门子200smart数据

发现网上很多关于python通过s7协议控制200smart的代码都失败,我猜应该是版本的问题。自己捣鼓了半天,终于测试成功


from snap7 import util,client

my_plc = client.Client()  #建立一个客户端对象
my_plc.set_connection_type(3) #如果是200smart,必须有此段代码。1200,1500可以不写。
my_plc.connect("192.168.11.9",0,1)  #连接plc,参数分别为ip ,卡号,槽号。200smart为0和1

state=my_plc.get_connected() #用来判读是否连接成功 返回值为true 和false
# print(state)


 #注意,这里的参数有坑,最新的sanp7协议是这样写,后面1代表V区,0代表起始地址,10代表字节数量
 #注意,这里0对应VB0,1对应vb1以此类推。
data=my_plc.read_area(client.Areas.DB,1,0,10)


my_data = util.get_byte(data,5)

m=util.get_word(data,0) #相当于vw0
m2=util.get_word(data,2)  #相当于vw2
m3=util.get_word(data,4)  #相当于vw4
m4=util.get_word(data,6)  #相当于vw6



print(m)
print(m2)
print(m3)
print(m4)

my_plc.disconnect() #断开连接
my_plc.destroy() #销毁客户端对象

python通过S7协议读取西门子200smart数据_第1张图片

 python通过S7协议读取西门子200smart数据_第2张图片

from HslCommunication import SiemensS7Net
from HslCommunication import SiemensPLCS





#bool read write test


def printReadResult(result):
    if result.IsSuccess:
        print(result.Connect)
    else:
        print('failed'+result.Message)

def printWriteReslut(result):
    if result.IsSuccess:
        print('sucess')
    else:
        print('failed' + result.Message)

if __name__ == '__main__':
    siemens = SiemensS7Net(SiemensPLCS.S200Smart,'192.168.12.10')
    # '''连接服务器,也可放在窗口的Load方法中,一般建议使用长连接,速度更快,又是线程安全(下面使用了长连接),如果不连接,直接读取,就是短连接'''
    if siemens.ConnectServer().IsSuccess==False:
        print('connect failed')
    else:
        #bool read write test
        siemens.WriteBool("M80.6",True)
        printWriteReslut(siemens.ReadBool("M80.6"))

        #byte read write test
        siemens.WriteByte("M100",58)
        printWriteReslut(siemens.ReadByte("M100"))

        #int16 read write test
        siemens.WriteInt16("M102",12358)
        printWriteReslut(siemens.ReadInt16("M102"))

        data = siemens.ReadByte("V100").Content #读取v100的值
        print(data)

        # 断开连接
        # siemens.ConnectClose()
from snap7 import util, client

my_plc = client.Client()  # 建立一个客户端对象
my_plc.set_connection_type(3)  # 如果是200smart,必须有此段代码。1200,1500可以不写。
my_plc.connect("192.168.11.9", 0, 1)

class plcData(QThread):
    def __init__(self,plc):
        super(plcData, self).__init__()
        self.plc=plc


    def run(self):
        self.check_plc_state()

    def check_plc_state(self):
        short_data=None
        QThread.sleep(100)
        end_data=None
        if short_data==end_data:
            print('通讯异常')
            self.plc.close()





class PlcThread(QThread):
    def __init__(self,plc):
        super(PlcThread, self).__init__()
        self.plc=plc

    def run(self):
        while True:
            if self.plc.get_connected()==False:

                try:
                    self.plc.connect("192.168.11.9", 0, 1)
                except Exception as e:
                    pass
            else:
                #读取数据
                try:
                    # da=#
                    # 区
                    print('数据读取')
                except Exception as e:
                    pass







class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("的学习")
        self.resize(500,500)
        self.setup_ui()

        self.plc = my_plc = client.Client()  # 建立一个客户端对象 单独开个线程去处理
        self.plc.set_connection_type(3)  # 如果是200smart,必须有此段代码。1200,1500可以不写。


        self.t = PlcThread()


    def setup_ui(self):
        self.btn=QPushButton('btn',self)
        self.btn.clicked.connect(self.btn_cick)

    def btn_click(self):
        self.plc.connect("192.168.11.9", 0, 1)
        self.plc.get_connected()
        #d读取数据,用一个线程






if __name__ == '__main__':
    import sys
    app=QApplication(sys.argv)

    win=Window()
    win.show()





    sys.exit(app.exec_())

写PLC

写PLC用到的方法为 write_area(area,dbnumber,start,data)

说明如下:area表示往哪个区去写,如:plc.write_area(client.Areas.DB,1,2,bytes)

                dbnumber:如果是smart200plc,要填1,1200/1500填0

                start 开始的地址,指字节,如上面的2,代表vb2

                bytes 代表长度,如果写一个位,就用一个字节

具体分三步:

1,bty_arrays = read_area()或bty_arrays = bytearay(变量类型所占的大小)

2.用snap7.util类来更改字节数组,bool类型用1个字节,word用2个字节等例如

set_bool(_bytearray,byte_index,bit,value)字节数组,字节索引,位索引,要写入的值

3.通过write_area(area,dbnumber,start,data)写入到plc相对应的区

    def connect_200smart(ip,plc_mode=3,rack=0,slot=1):

        my_plc = client.Client()
        my_plc.set_connection_type(plc_mode) #200smart 要设置
        my_plc.connect(ip,rack,slot)

        return my_plc



    plc=connect_200smart("192.168.2.1")

    print(plc.get_connected())

    bytes=plc.read_area(client.Areas.DB,1,0,10)#说明 smart200 的V区要填写1,0代表VB0
   



    util.set_bool(bytes, 0, 0, 0)
    plc.write_area(client.Areas.DB,1,0,bytes)  #说明 smart200 的V区要填写1,0代表VB0

    util.set_bool(bytes,0,1,0)
    plc.write_area(client.Areas.DB,1,1,bytes)

    util.set_bool(bytes,0,3,0)
    plc.write_area(client.Areas.DB,1,2,bytes)


#用一个字节数组,因为对位操作,一个字节够了
    buf=bytearray(1) #第一步,创建一个字节数组
  
    util.set_bool(buf,0,1,0) #第二步,把该字节的第一个位设为TRUE
    plc.write_area(client.Areas.DB,1,0,buf) #第三步把更改的字节放到V区,vb0里。

        

import threading
import time
from PyQt5.Qt import *
from snap7 import client,util


class PlcData():
    def __init__(self):
        self.db_dd12 :float = None
        self.db_d24:float = None

    def checkConnectState(self,plc):
        self.t = threading.Thread(target=self.run_thread,args=(plc,),daemon=True)
        self.t.start()

    def run_thread(self,plc):
        while True:
            start=self.db_d24
            time.sleep(1000)
            end = self.db_d24
            print(f"start={start}--end={end}")

            if start==end:
                QMessageBox.warning(self,"waringing","通讯异常")
                plc.disconnect()







class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("的学习")
        self.resize(500,500)
        self.setup_ui()


    def setup_ui(self):
        self.label = QLabel('info',self)
        self.label.move(100,50)

        self.btn=QPushButton('start',self)
        self.btn.move(100,200)
        self.btn.clicked.connect(self.btn_click)

        self.plc = client.Client()
        self.plc.set_connection_type(3)
        self.plcdata = PlcData()

    def btn_click(self):
        try:
            self.plc.connect("192.168.2.20",0,1)
            self.t=threading.Thread(target=self.getdata)
            self.plcdata.checkConnectState(self.plc)
        except:
            pass


    def getdata(self):
        while True:
            print('11111')
            if not self.plc.get_connected():
                try:
                    self.plc.connect('192.168.2.20',0,1)
                except Exception as e:
                    print(e)
                else:
                    #成功直接读数据
                    try:
                        bytearray = self.plc.db_read(1, 0, 2)
                        self.plcdata.db_d24 = util.get_word(bytearray,0)
                        self.label.setText(str(self.plcdata.db_d24))
                    except Exception as e:
                        print(e)














if __name__ == '__main__':
    import sys
    app=QApplication(sys.argv)

    win=Window()
    win.show()





    sys.exit(app.exec_())










你可能感兴趣的:(python通信,python基础学习,python,开发语言)