mshaver Posted February 24, 2014 Share Posted February 24, 2014 I have a process (say a specialized homing routine) running in a motion program and I want to have a watchdog timer running such that if it expires before the routine is complete I cancel the process and declare a fault. I can't find anything "built in". Am I overlooking a built in method? I've read and implemented some logic I found in older posts. The examples of comparing sys.time and a value x seconds from now in a "while loop" in the same program that is the watchdog simply don't work. I built in some hooks so I could see what happens to sys.time and a done bit from the homing routine program, and neither one ever updates. The system truly is in an infinite loop and does not actually check sys.time each time it loops. I implemented an example that uses a subprogram, and this does work, but it's not even close to deterministic. Tests showed that for a 1 second timer, usually the actual time was closer to 1.5 to 2 seconds and sometimes as much as 3 to 4 seconds. Am I overlooking something more native? I'm more used to controllers that have native timer objects or OOP environments such as C#, VB.net, Java, and so on that have native timer objects. What about using the RTI for PLC 1 and using counters within PLC 1, starting, stopping, and clearing them from other programs? How deterministic might this approach be? Anyone have more elegant solutions? Thanks; MShaver mshaver@pekoprecision.com Link to comment Share on other sites More sharing options...
Omron Forums Support Posted February 24, 2014 Share Posted February 24, 2014 Hi, Checking Sys.Time has worked for me every time. Can you post your code? Maybe you missed something. Link to comment Share on other sites More sharing options...
mshaver Posted February 25, 2014 Author Share Posted February 25, 2014 From an earlier post: open plc 1 L1 = sys.time + 0.01; while(L1 > sys.time) {}; p2 = p2 + 1; close // So based on the above, I wrote this as my watchdog on the homing process. // The sends are just hooks I added to see why the thing never timed out. // When this runs, I get the first four sends over and over hundreds of times without ever // stopping. Keeps running long after HomeInProgress has gone to zero. It continues to return // the same value for sys.time over and over without ever advancing. // It is simply not obtaining an updated value for sys.time. open plc 21 send 2,"Checking in plc 21" send 2,"Timer1=%d\n",Timer1 send 2,"Sys.time=%d\n",Sys.Time send 2,"HomeInProgress=%d\n",Motor[1].HomeInProgress //Wait until time out or home in progress = 0 while ((Sys.Time > Timer1) && (Motor[1].HomeInProgress==0)) {} send 2,"Proceeding in plc 21" send 2,"Timer1=%d\n",Timer1 send 2,"Sys.time=%d\n",L1 send 2,"HomeInProgress=%d\n",Motor[1].HomeInProgress if (Motor[1].HomeInProgress!=1) { if (Motor[1].HomeComplete) { send 2,"Motor 1 homed successfully" } else { send 2,"Motor 1 homing failed" } send 2,"Exiting plc 21"; disable plc 21 } if (sys.Time > Timer1) { cmd"&1A" send 2,"Motor 1 homing timed out" send 2,"Exiting plc 21"; disable plc 21 } close // So I tried the following: Same result. The first 4 sends repeat continuously long after I know 3 seconds has elapsed and long after the home in progress has gone to zero in the status window. open plc 21 send 2,"Checking in plc 21" send 2,"Timer1=%d\n",Timer1 send 2,"Sys.time=%d\n",Sys.Time send 2,"HomeInProgress=%d\n",Motor[1].HomeInProgress //Wait until time out or home in progress = 0 if ((Sys.Time > Timer1) || (Motor[1].HomeInProgress==0)) { send 2,"Proceeding in plc 21" send 2,"Timer1=%d\n",Timer1 send 2,"Sys.time=%d\n",L1 send 2,"HomeInProgress=%d\n",Motor[1].HomeInProgress if (Motor[1].HomeInProgress!=1) { if (Motor[1].HomeComplete) { send 2,"Motor 1 homed successfully" } else { send 2,"Motor 1 homing failed" } send 2,"Exiting plc 21"; disable plc 21 } if (sys.Time > Timer1) { cmd"&1A" send 2,"Motor 1 homing timed out" send 2,"Exiting plc 21"; disable plc 21 } } close Link to comment Share on other sites More sharing options...
daves Posted February 25, 2014 Share Posted February 25, 2014 This worried me so I investigated. I only looked at the first case. There are a couple of issues with the logic you have used: Firstly this cannot be all the code as you don't show that you start the home or how you initialise Timer1. I will assume you start the home, set Timer1=Sys.Time+3, start the PLC. //Wait until time out or home in progress = 0 while ((Sys.Time > Timer1) && (Motor[1].HomeInProgress==0)) {} should be //Wait until time out or home in progress = 0 while ((Sys.Time < Timer1) && (Motor[1].HomeInProgress==1)) {} you want to wait WHILE the timeout has not been reached and WHILE the home is still in progress. In your code, during the home, your while will just drop through. The 7th send send 2,"Sys.time=%d\n",L1 should be send 2,"Sys.time=%d\n",Sys.Time You say you get the first four sent messages (or what you call 'hooks') repeatedly but I found the first eight sends repeated with the bad logic. This is because during the home and timeout period your 'while' drops through and neither of the following 'if' conditions are met so the PLC executes again repeating the eight messages. PLCs are effectively loops. A quick experiment shows mine running at 1000Hz. So your example was buffering out 8000 message lines a second. This looks slow in the Unsolicited window as it is catching up with these buffered messages, and appears unchanging as there are 8000 messages before Sys.Time will have a new value. Link to comment Share on other sites More sharing options...
kmonroe023 Posted February 25, 2014 Share Posted February 25, 2014 mshaver, There is a timer subroutine that works quite nicely for PLC applications. It should be in the project solution under the 'Libraries' folder (subprog2.pmc). It takes care of all the while loop nonsense, all you need to do is specify the time in seconds. Usage in a plc ... call timer (0.250); // dwell PLC for 250msec ... If you don't have the subroutine in your project, just add a new pmc file to your Libraries folder and add this code to it: /****************************************/ // Sample calling timer SUBPROGRAM // open plc 1 // call timer (3); // have a 3 second delay // close // // Brad Pedersen Sept 9th 2010 /****************************************/ open subprog timer (time) local EndTime; local count; EndTime = Sys.Time + time do count++ while (EndTime > Sys.Time) close Of course you can forgo calling the subroutine and implement this code right in your plc, adding whatever other conditionals are required. Link to comment Share on other sites More sharing options...
mshaver Posted February 26, 2014 Author Share Posted February 26, 2014 To DAVES: Thanks, makes much more sense now. Was obviously confused with how the DT deals with the while loops, what gets scanned what doesn't upon reentry, etc. Works great now. Was able to consolidate everything into one program now that I know and "trust" what the DT is doing in these loops. To kmonroe023: Also thanks, will give this a try. Different animal this PPMAC. Been programming every kind of platform under the sun for 40 years. At times the PPMAC makes me feel like I'm in my very first programming class all over again with that feeling of "What the ... Thanks Link to comment Share on other sites More sharing options...
Recommended Posts