Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Application slow to update values through script

williamc
2014-01-17
2015-04-16
  • williamc - 2014-01-17

    I have a function block reading back a mapped IO variable. The function has an input which effectively changes which variable to return.

    When I look at this function running under CoDeSys it is very quick to change as I change the input value.

    However, when I perform the same action through script there is quite a delay (almost 3 seconds) before the variable becomes updated.

    Any suggestions as to why?

     
  • mkeller - 2014-01-24

    Hi.

    williamc hat geschrieben:
    However, when I perform the same action through script there is quite a delay (almost 3 seconds) before the variable becomes updated.

    The monitoring works through events which depend on the main message queue. While running a script the main message queue is mostly blocked. Some methods of the CODESYS script engine contain some code to process the main message queue.

    Sometimes that is not enough and you have to add one or more of ```

    system.delay(n)

    ``` in your script. It processes the main message queue while waiting for the specified time to elapse. The time should be bigger then 200ms but it depends on the PLC, the amount and type of expressions which are monitored at that moment.

    Regards,
    Martin

     
  • zhou - 2015-04-15

    I have the same issue, I've wrote a script to write a variable then read the it's value. And found if the time delay between write and read to small, the read value didn't changed after I've changed it.

    from __future__ import print_function
    import os
    \# Read / Write Variable without opening codesys
    \# this file will be called from a batch file.
    \#
    \# Project name will be set with batch and transfered via enviroment variable
    \#######################
    \# Open Codesys project
    \#######################
    def openProject(PROJECT):
       print(" opening project: ", PROJECT)
       proj = projects.open(PROJECT)
    \##############################
    \# creating online application
    \##############################
    def createOnlineApp():
       print(scriptName, ": creating online application ...")
       # onlineApp = online.create_online_application(proj.active_application)
       # if it is already online manually
       global onlineApp
       onlineApp = online.create_online_application()
    \##############################
    \# Lgoin
    \##############################
    def login():
       print(scriptName, ": login ...")
       global onlineApp
       onlineApp.login(OnlineChangeOption.Try, True)
       if not onlineApp.application_state == ApplicationState.run:
          print(scriptName, ": Run Application")
          onlineApp.start()
       else:
          print(scriptName, ": Application is already running")
    var="Sequencer.iPythoncounter"
    iValue   = 0
    \# scriptname
    scriptName = os.path.basename(__file__)
    def ReadVar():
       Value = onlineApp.read_value(var)   # INT#5
       # print(" type of Value is:", type(Value))
       #print("variables to read:",var)
       # print(" value of %s is: %s"% (var, Value))
       print(" read: ", Value)
    def WriteVar():
       ValueToWrite = str(iValue)
       onlineApp.set_prepared_value("Sequencer.iPythoncounter", ValueToWrite)
       onlineApp.write_prepared_values()
       
       
    if __name__ == '__main__':
       print("%s: ####### script is running as main ##############" %(scriptName))
       global onlineApp
       createOnlineApp()
       login()
       
       for i in range (1,11):
          iValue = i
          #write variables
          WriteVar()
          print("written: ", iValue)
          # sleep 10 ms
          system.delay(10)
          # Read variables
          ReadVar()
          
          
             
       
    

    In my script I've only changed a Int variable. It worked fine if I increase:

    system.delay(300)
    
    1. But if I wrote 3 variables and then read them, I had to increase system.delay() to 500 ms. Does it depend on quantity of variables?
    2. if I call this python script from a batch file (without opening codesys), this problem is more critical, the delay time needs to be set even higher, to 1000 ms, why?

    IMG: read_write.png

     
  • mkeller - 2015-04-15

    Hi zhou.

    zhou hat geschrieben:
    1. But if I wrote 3 variables and then read them, I had to increase system.delay() to 500 ms. Does it depend on quantity of variables?

    Yes, and it also depends on other factors. The data type of the variable(s), for example. The monitoring was developed for the debugging of IEC code. What do you want to accomplish with your script?

    zhou hat geschrieben:
    2. if I call this python script from a batch file (without opening codesys), this problem is more critical, the delay time needs to be set even higher, to 1000 ms, why?

    What do you mean with "without opening codesys"? Does your batch file execute CODESYS with the parameter for executing a python script?

    BR
    Martin

     
  • zhou - 2015-04-16

    Hello Martin,

    M.Keller hat geschrieben:
    Yes, and it also depends on other factors. The data type of the variable(s), for example. The monitoring was developed for the debugging of IEC code. What do you want to accomplish with your script?

    the script above has been simplified to demonstrate the phenomenon. Actually I have a script for testing a function block in codesys (similar like unittest), the main function of this script is:
    1. write values to the inputs of FB
    2. read output values of FB as actual outputs
    3. compare actual output with expected outputs (test pass or fail)
    4. repeat 1-3 with different values of inputs (I have more than 200 testing inputs)

    After executing this script, I've found as you mentioned, a time delay between step 1 and 2 is necessary, and I was confused about how much should the time delay should be and its background.

    Question:
    Could you explain more about "The monitoring was developed for the debugging of IEC code"?
    Any suggestion about the application of my script? better ideal (solution)?

    M.Keller hat geschrieben:
    What do you mean with "without opening codesys"? Does your batch file execute CODESYS with the parameter for executing a python script?

    @echo off
    SET PROJECT=C:\Users\gong\Documents\01 MeinArbeit\10 Aufgaben\Sequencer\LIB\Sequencer.library
    echo Starting Codesys ....
    start /wait CoDeSys.exe --Profile="CODESYS V3.5 SP4 Patch1 pbF" --noUI --runscript="C:\Users\gong\Documents\01 MeinArbeit\10 Aufgaben\Sequencer\TestScript\unittest\unittest.py"
    pause
    

    I've listed my batch file above. If I call the script from batch file I need to increase the delay time between step 1 and 2, as I run this script directly via "Tools->scripting->execute script file".

     
  • mkeller - 2015-04-16

    Hi zhou.

    zhou hat geschrieben:
    Could you explain more about "The monitoring was developed for the debugging of IEC code"?

    The values are collected and sent in the background to minimize the effect on the execution of the application(s). Also the debugging is done by humans which normally would not notice the delay. I had the same problems when implementing new stuff for the IEC Unit Test of the Test Manager.

    zhou hat geschrieben:
    4. repeat 1-3 with different values of inputs (I have more than 200 testing inputs)

    Are we talking about a table of all possible input values and expected output results? Why not use unit testing?! You can split the table into smaller chunks if you don't want to use only one unit test for the whole table.

    Are you using the python script for Continuous Integration?

    BR
    Martin

     
  • zhou - 2015-04-16

    hello Martin,

    M.Keller hat geschrieben:
    Are we talking about a table of all possible input values and expected output results? Why not use unit testing?! You can split the table into smaller chunks if you don't want to use only one unit test for the whole table.

    exactly, I don't know much about unittesting. I've just searched on internet for some code of unittesting and tried to modified it to my own use.
    Maybe you could help me have a look at my script below.
    Is a Test Manager Plugin for codesys necessary?

    thanks a lot
    Zhou

    testGetResource.py [4.89 KiB]

     
  • mkeller - 2015-04-16

    Hi zhou.

    zhou hat geschrieben:
    exactly, I don't know much about unittesting. I've just searched on internet for some code of unittesting and tried to modified it to my own use.
    Maybe you could help me have a look at my script below.

    Unit tests are normally written in the same programming language as the code you want to test. For CODESYS it would be IEC 61131-3. The unit tests used with the Test Manager are written in ST and use the CAA Behaviour Model (see CODESYS help). Our own QA use it to test our compilers and software stacks.

    zhou hat geschrieben:
    Is a Test Manager Plugin for codesys necessary?

    No, the plug-in already exists. The CODESYS Test Manager

    BR
    Martin

     

Log in to post a comment.