Codementor Events

Motor control PLC in Python

Published Sep 01, 2019Last updated Sep 02, 2019

Project description

We have different types of devices like sov, motor, analog, digital, control valves etc. Each type of device has 100 items.

Now our software continuously monitors with the PLC to read some property of each type according to which we need to write some property.

As an example, if motor on command is high then we need to write on feedback at PLC end high. At the moment, I face the problem that it takes too much time to update.

Now I describe my software architecture:

  1. I make individual class for each types of device. As an example for motor:

    class Fn_Motor1D:
    
    
    
        def __init__(self,com,df,idxNo):
    
            self._idxNo =idxNo
            self.gen = com
            self.df = df
            self.setup()
            self.initilizedigitalinput()
    
    
        def setup(self):
            try:
    
                for tag,col in self.readalltags():
    
                    if col==3:
                        self.cmd = str(tag)
    
    
                    if col == 4:
                        self.runingFB = str(tag)
    
    
                    if col == 5:
                        self.remoteFB = str(tag)
    
    
                    if col == 6:
                        self.healthyFB = str(tag)
    
    
                    if col == 7:
                        self.readyFB = str(tag)
    
    
                    if col == 8:
                        self.mccbonFeedBack = str(tag)
    
                    if col == 9:
                        self.overloadFeedBack = str(tag)
    
    
                    if col == 10:
                        self.faultFB =str(tag)
    
    
                    if col == 11:
                        self.delaytime = tag
    
    
    
            except Exception as e:
                print("exception raise",e.args)
                log_exception(e)
    
        def initilizedigitalinput(self):
            try:
                if len(self.healthyFB) > 3:
                    self.gen.writegeneral.writenodevalue(self.healthyFB, 1)
                else:
                    pass
    
                if len(self.remoteFB) > 3:
                    self.gen.writegeneral.writenodevalue(self.remoteFB, 1)
                else:
                    pass
    
                if len(self.readyFB) > 3:
                    self.gen.writegeneral.writenodevalue(self.readyFB, 1)
                else:
                    pass
    
                if len(self.mccbonFeedBack) > 3:
                    self.gen.writegeneral.writenodevalue(self.mccbonFeedBack, 1)
                else:
                    pass
    
                if len(self.overloadFeedBack) > 3:
                    self.gen.writegeneral.writenodevalue(self.overloadFeedBack, 0)
                else:
                    pass
    
                if len(self.faultFB) > 3:
                    self.gen.writegeneral.writenodevalue(self.faultFB, 0)
                else:
                    pass
            except Exception as e :
                log_exception(e)
    
    
        def process(self):
    
            try:
    
                oncommandvalue = self.gen.readgeneral.readtagvalue(self.cmd)
                if oncommandvalue:
                    sleep(self.delaytime)
                    self.gen.writegeneral.writenodevalue(self.runingFB, 1)
                else:
                    self.gen.writegeneral.writenodevalue(self.runingFB, 0)
    
            except Exception as e:
                log_exception(e)
    
       
    
        def readalltags(self):
            n = 3
            row, col = self.df.shape
            print(col)
            while n < col:
                data = self.df.iloc[self._idxNo, n]
                yield data,n
                n = n + 1
    
  2. Call all motor devices at one class and make listofallmotor1d devices.

    class Cal_AllMotor1D:
    
        def __init__(self,df,com):
            self.df = df
            self.com = com
            self.listofmotor1D = []
            self.setup()
    
    
        def setup(self):
            try:
                n =0
                self.listofmotor1D.clear()
                while n< len(self.df.index):
                    self.df.iloc[n, 0] = Fn_Motor1D(self.com, self.df, n)
                    self.listofmotor1D.append(self.df.iloc[n,0])
                    n = n + 1
    
    
            except Exception as e :
                print(e.args)
                log_exception(e)
    
        def process(self):
            n = 0
            while n < len(self.listofmotor1Dir):
                self.listofmotor1Dir[n].process()
                n = n + 1
    
    
    
    
        @property
        def listofmotor1Dir(self):
            if len(self.listofmotor1D) > 0:
                return self.listofmotor1D
    
  3. Now I make AllDevices class where I call the all device and write monitoring process:

    import callallmotor1D
    import callallmotor2D_V1
    import callallsov1S_V1
    import callallsov2S_V1
    import calallanalog_V1
    import calallcontrolvalves_V1
    import callallvibrofeeder_V1
    import callallconveyor_V1
    
    import pandas as pd
    
    class AllDevices:
    
        def __init__(self,comobject):
    
    
            self._comobject = comobject
            dfM1D = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='Motor1D')
            dfM2D = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='Motor2D')
            dfsov1S = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='Valve1S')
            dfsov2S = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='Valve2S')
            dfanalog = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='AnalogTx')
            dfcontrolvalve = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='ControlValves')
            dfvibrofeeder = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='VibroFeeder')
            dfconveyor = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='Conveyor')
    
    
            self.allmotor1dobjects = callallmotor1D.Cal_AllMotor1D(dfM1D, comobject)
            self.allmotor2dobjects =  callallmotor2D_V1.Cal_AllMotor2D(dfM2D,comobject)
            self.allsov1sobjects = callallsov1S_V1.Cal_AllSov1S(dfsov1S,comobject)
            self.allsov2sobjects = callallsov2S_V1.Cal_AllSov2S(dfsov2S, comobject)
            self.allanalogobjects = calallanalog_V1.Cal_AllAnalogInputs(dfanalog,comobject)
            self.allcontrolvalveobjects = calallcontrolvalves_V1.Cal_AllControlValve(dfcontrolvalve,comobject)
            self.allvibrofeederobjects = callallvibrofeeder_V1.Cal_AllVibroFeeder(dfvibrofeeder,comobject)
            self.allconveyorobjects = callallconveyor_V1.Cal_AllConveyor1D(dfconveyor,comobject)
    
    
    
        def allmotor1dprocessing(self):
            self.allmotor1dobjects.process()
            self.allmotor1dobjects.process()
    
        def allmotor2dprocessing(self):
            self.allmotor2dobjects.process()
    
        def allsov1sprocessing(self):
            self.allsov1sobjects.process()
            
        def allanalogsprocessing(self):
            self.allanalogobjects.process()
    
        def allcontrolvaleprocessing(self):
            self.allcontrolvalveobjects.process()
    
        def allvibrofeederprocessing(self):
            self.allvibrofeederobjects.process()
    
        def allconveyorprocessing(self):
            self.allconveyorobjects.process()
    
  4. At the end I all devices class in my main UI and run seperate thread each device type:-

                 def allmotor1dprocess():
                         while True :
                                 self.callalldevices.allmotor1dprocessing()
    
                 def allmotor2dprocess():
                         while True:
                                 self.callalldevices.allmotor2dprocessing()
    
    
    
                 def allsov1sprocess():
                         while True:
                                 self.callalldevices.allsov1sprocessing()
    
    
    
                 def allananlogprocess():
                         while True:
                                 self.callalldevices.allanalogsprocessing()
    
                 def allcontrolvalveprocess():
                         while True:
                                 self.callalldevices.allcontrolvaleprocessing()
    
                 def allconveyorprocess():
                         while True:
                                 self.callalldevices.allconveyorprocessing()
    
    
                self.writeallmotor1dthread = threading.Thread(target=allmotor1dprocess)
             self.writeallmotor2dthread =threading.Thread(target=allmotor2dprocess)
             self.writeallsov1sthread1 = threading.Thread(target=allsov1sprocess)
             self.writeallsov1sthread2 = threading.Thread(target=allsov1sprocess2)
             self.writeallsov2sthread = threading.Thread(target=allsov2sprocess)
             self.writeallanalogthread = threading.Thread(target=allananlogprocess)
             self.writeallcontrolvalvethread = threading.Thread(target=allcontrolvalveprocess)
             self.writeallconveyorthread = threading.Thread(target=allconveyorprocess)
    
             self.writeallmotor1dthread.start()
             self.writeallmotor2dthread.start()
             self.writeallsov1sthread1.start()
             self.writeallsov1sthread2.start()
             self.writeallsov2sthread.start()
             self.writeallanalogthread.start()
             self.writeallcontrolvalvethread.start()
             self.writeallconveyorthread.start()
    

In this software architecture I really face problem to update the plc data.

As an example, let's suppose that I give on command for a motor. This will take time to update its run feedback. So, I need your expert view on this.
Please let me know how I can improve my coding to get process faster.

Discover and read more posts from Subrata Mitra
get started
post commentsBe the first to share your opinion
Show more replies