Python编写软件与从倍福PLC通讯软件

本文介绍了一款使用Python编写的软件,该软件能与倍福PLC进行通讯。文章详细阐述了软件的界面设计以及关键代码的分享,展示了Python在后端通讯领域的应用。
摘要由CSDN通过智能技术生成

一、软件界面

二、代码分享

from tkinter import *
from tkinter import ttk
import time
import pyads

# # 打包成.exe的方法:pyinstaller -w -p C:\Windows\System32\downlevel  -i D:\Python_Test\03-pycharm\6\001.ico D:\Python_Test\03-pycharm\6\Ads_Test.py (xxx:想要打包的文件夹)
class GUI_DISIN():

    def __init__(self,GUI_Name):
        self.GUI_Name=GUI_Name
        self.func = ''

    #初始化设计窗口
    def set_init_Gui(self):
        self.GUI_Name.title('倍福通讯测试')
        self.GUI_Name.geometry('800x200+10+10')


        #添加标签
        self.label1 = Label(self.GUI_Name,text="输入变量名")
        self.label1.grid(row=0,column=0)
        #下拉框标题
        self.label5 = Label(self.GUI_Name, text="数据类型")
        self.label5.grid(row=0, column=5)
        self.label2 = Label(self.GUI_Name,text="变量值")
        self.label2.grid(row=0,column=10)
        self.label3 = Label(self.GUI_Name, text="日志输出")
        self.label3.grid(row=0, column=13)
        self.label4 = Label(self.GUI_Name, text="")
        self.label4.grid(row=0, column=15)
        self.label5 = Label(self.GUI_Name, text="NetID:")
        self.label5.grid(row=2, column=0)
        self.label6 = Label(self.GUI_Name, text="Port:")
        self.label6.grid(row=2, column=5)


        #添加文本框
        #变量名输入
        self.text1 = Text(self.GUI_Name,width=20,height=2)
        self.text1.grid(row=1,column=0)
        #数据值输出
        self.text2 = Text(self.GUI_Name,width=20,height=2)
        self.text2.grid(row=1,column=10)
        #日志输出
        self.text3 = Text(self.GUI_Name,width=30,height=2)
        self.text3.grid(row=1,column=13)
        #实时时间显示
        self.text4 = Text(self.GUI_Name,width=18,height=2,font=('times',10,'bold'))
        self.text4.grid(row=0,column=14)
        #NetID
        self.text5 = Text(self.GUI_Name,width=20,height=2)
        self.text5.grid(row=3,column=0)
        #Port
        self.text6 = Text(self.GUI_Name,width=20,height=2)
        self.text6.grid(row=3,column=5)

        #按钮-单次读取
        self.button1 = Button(self.GUI_Name,text='单次读取',bg='lightblue',
                              width=10,command=self.ReadData_Once)
        self.button1.grid(row=1,column=14)
        #按钮-连续读取
        self.button2 = Button(self.GUI_Name,text='循环读取',bg='lightblue',
                              width=10,command=self.ReadData_Continuous)
        self.button2.grid(row=2,column=14)
        #按钮-取消连续读取
        self.button2 = Button(self.GUI_Name,text='循环读取停止',bg='lightblue',
                              width=10,command=self.Cancel_ReadData_Continuous)
        self.button2.grid(row=3,column=14)

        #添加下拉框
        value = StringVar()
        value.set('CCC')
        values = [
                'PLCTYPE_BOOL',
                'PLCTYPE_BYTE',
                'PLCTYPE_DWORD',
                'PLCTYPE_DINT',
                'PLCTYPE_INT',
                'PLCTYPE_LREAL',
                'PLCTYPE_REAL',
                'PLCTYPE_SINT',
                'PLCTYPE_STRING',
                'PLCTYPE_TOD',
                'PLCTYPE_UBYTE',
                'PLCTYPE_UDINT',
                'PLCTYPE_UINT',
                'PLCTYPE_USINT',
                'PLCTYPE_WORD',
                'PLCTYPE_LINT',
                'PLCTYPE_ULINT',
                'PLCTYPE_DATE',
                'PLCTYPE_DATE_AND_TIME',
                'PLCTYPE_DT',
                'PLCTYPE_TIME,'
        ]
        #   下拉列表控件
        self.combobox = ttk.Combobox(
            master=self.GUI_Name,  # 父容器
            height=10,  # 高度,下拉显示的条目数量
            width=15,  # 宽度
            state='readonly',  # 设置状态 normal(可选可输入)、readonly(只可选)、 disabled
            cursor='arrow',  # 鼠标移动时样式 arrow, circle, cross, plus...
            font=('', 15),  # 字体
            textvariable=value,  # 通过StringVar设置可改变的值
            values=values,  # 设置下拉框的选项
        )
        self.combobox.grid(row=1,column=5)


        #   实时显示时间
        self.tick()

    def ReadData_Continuous(self):
        #循环读取变量
        i=1
        print(1)
        self.ReadData_Once()
        self.func = self.GUI_Name.after(10, self.ReadData_Continuous)  # .after函数可以循环实现该函数

    def Cancel_ReadData_Continuous(self):
        #取消连续读取
        self.GUI_Name.after_cancel(self.func)

    def ReadData_Once(self):
        # 单次读取变量
        pass

        #   读取NetID
        NetID = self.text5.get(1.0,END).strip()
        #   读取Port
        Port = int(self.text6.get(1.0,END).strip())
        #   打开PLC
        plc = pyads.Connection(NetID, Port)
        plc.open()

        #   通过变量名去读值
        src ='.'+ self.text1.get(1.0,END).strip()
        print(src)
        src_type = self.combobox.get().strip()
        # print(type(src_type))
        # 得到数据类型
        src_type1 =self.Get_ParaType(src_type)
        # src_type = pyads.PLCTYPE_BOOL
        print(type(src_type1))

        try:
            if src !='' and src_type !='':
                print('okk')
                result = ''
                result = plc.read_by_name(data_name=src,plc_datatype=src_type1)
                print(result)
                if result != '':
                    try:
                        self.text2.delete(1.0, END)
                        self.text2.insert(1.0, result)
                        str1 = '变量--'+str(src) + '--读取成功!'
                        self.log(str1)
                    except:
                        self.text2.delete(1.0, END)
                        self.log('读取字符为空失败')
        except :
            self.text2.delete(1.0, END)
            self.log('打开端口失败')

    def Get_ParaType(self,input_str):
        #   实现字符串转变量类型功能
        if input_str == 'PLCTYPE_BOOL':
            return pyads.PLCTYPE_BOOL
        elif input_str == 'PLCTYPE_BYTE':
            return pyads.PLCTYPE_BYTE
        elif input_str == 'PLCTYPE_DWORD':
            return pyads.PLCTYPE_DWORD
        elif input_str == 'PLCTYPE_DINT':
            return pyads.PLCTYPE_DINT
        elif input_str == 'PLCTYPE_INT':
            return pyads.PLCTYPE_INT
        elif input_str == 'PLCTYPE_LREAL':
            return pyads.PLCTYPE_LREAL
        elif input_str == 'PLCTYPE_REAL':
            return pyads.PLCTYPE_REAL
        elif input_str == 'PLCTYPE_SINT':
            return pyads.PLCTYPE_SINT
        elif input_str == 'PLCTYPE_STRING':
            return pyads.PLCTYPE_STRING
        elif input_str == 'PLCTYPE_TOD':
            return pyads.PLCTYPE_TOD
        elif input_str == 'PLCTYPE_UBYTE':
            return pyads.PLCTYPE_UBYTE
        elif input_str == 'PLCTYPE_UDINT':
            return pyads.PLCTYPE_UDINT
        elif input_str == 'PLCTYPE_UINT':
            return pyads.PLCTYPE_UINT
        elif input_str == 'PLCTYPE_USINT':
            return pyads.PLCTYPE_USINT
        elif input_str == 'PLCTYPE_WORD':
            return pyads.PLCTYPE_WORD
        elif input_str == 'PLCTYPE_LINT':
            return pyads.PLCTYPE_LINT
        elif input_str == 'PLCTYPE_ULINT':
            return pyads.PLCTYPE_ULINT
        elif input_str == 'PLCTYPE_DATE':
            return pyads.PLCTYPE_DATE
        elif input_str == 'PLCTYPE_DATE_AND_TIME':
            return pyads.PLCTYPE_DATE_AND_TIME
        elif input_str == 'PLCTYPE_DT':
            return pyads.PLCTYPE_DT
        elif input_str == 'PLCTYPE_TIME':
            return pyads.PLCTYPE_TIME
        else:
            return ''


    def Get_Time(self):
        #   获取当前时间
        CurrentTime = time.strftime('%Y/%m/%d %H:%M:%S',time.localtime(time.time()))
        return CurrentTime

    #实时显示时间
    def tick(self):
        time1 = ''
        time2 =self.Get_Time()
        if time1!=time2:
            time1 = time2
            self.text4.delete(1.0,END)
            self.text4.insert(1.0,time1)
            #self.label4.config(text=time1)
            self.GUI_Name.after(10,self.tick) #.after函数可以循环实现该函数

    #   打印日志
    def log(self,src):
        pass
        CurrentTime = self.Get_Time()
        src =str(CurrentTime)+src
        self.text3.delete(1.0, END)
        self.text3.insert(1.0, src)
        src = ''


if __name__ == '__main__':
    print('-----程序开始-----')
    GUI = Tk()

    class_GUI = GUI_DISIN(GUI)
    class_GUI.set_init_Gui()


    GUI.mainloop()

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值