Author Topic: Program execution takes longer than Clk:1.0 Clock?  (Read 6731 times)

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Program execution takes longer than Clk:1.0 Clock?
« on: May 09, 2012, 04:34:43 PM »
I have a program that runs alright in the simulator, but not on the PLC(F1616-BA). I have 5 functions which run on the CLK:1.0s every time, State independent. There are some loops in there and a reading of 3x I-7017 over RS485. I also run an adaptation of the HMI sample code which runs every CLK:0.1 when State 1 is active.

One problem is that I'm not getting any reading from the I-7017s, even with a few sensors attached which work when the PLC is running the (much smaller) I-7017 sample code altered to read three 7017s at a time.
I also find that the HMI keystrokes require an unnaturally long depression of the key before they register, and then stay registered for a moment.

I was trying to think how I could have taken working code and corrupted it during cut/paste when I noticed that a variable which should increment every 0.1sec (off CLK:0.1s), was in reality incrementing much slower than that. After 60 seconds in real time, the counter represented 11 seconds. This makes me wonder if my code is causing the PLC to be in mid-execution of some part of a function when the CLK:1.0s forces it to go elsewhere. Or, just as bad, that the PLC continues what it's doing and ignores the request from the CLK:1.0s.

Can you please help me narrow down the possibilities?

Edit: improve clarity and spelling
« Last Edit: May 09, 2012, 04:37:16 PM by TravisB »

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #1 on: May 09, 2012, 05:16:49 PM »
I made some changes in the code and the keystroke issue has gone away, and the CLK:0.1s incrementing counter is now running at a speed which matches real-time.

I've added some LCD output which gives a success or fail message to the LCD. The response from each I-7017 should appear on a separate line. From this I have found I'm not getting a response from the 7017 which should print to the first line of the LCD, but I'm not getting anything on the other two lines. Now that I'm already suspicious of the PLC for the above mentioned reasons, I can't think about what else it could be.
Also, since I don't know what I did to reduce the problem, it's possible I'll commit the same mistake again, and suspect the PLC again, until someone tells me I'm being ridiculous.

garysdickinson

  • Expert Member
  • Posts: 464
  • Old PLC Coder
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #2 on: May 09, 2012, 09:27:15 PM »
Travis you have to be very careful with the coding of custom functions to ensure that they execute very quickly becuase the ladder logic scanning mechanism can not proceed until the function completes.

I didn't like the sample HMI code because of the polling of the keyboard I/O every 0.1s.  My version uses ladder logic to detect if a single key is pressed, and then and only then invokes a custom function.  Why waste time in a custom function when there is no key pressed, therefore there can't be anything to do.  

The the PLC comunicates with the I-7017 over RS-485 and the NETCMD$() function has to wait for the serial mesage to be transmitted to the I-7017, then processed by the I-7017 and then wait for a message to be send by the I-7017.  This whole process could easily take 100ms.  If you are talking to 3 I-7017s on the same scan your could be tying up the PLC for close to a 1/4 second every second!

I'd suggest that you poll I-7017 at the lowest rate that that makes sense.  Do any of your analog inputs change much in 1 second or 10 seconds or 100 seconds?  I worked with an 400 gallon aquarium that took about an hour to change 1 degree C with the heaters running full blast.  There is no point in checking it's temperature once a second.  I checked it once every minute and that was serious overkill.

For sake of arugument, lets say that you could safely poll your I-7017 once every 10 seconds.  Poll the first one at 10 seconds, the second one at 11 seconds, the third one at 12 seconds...

The following is the code that I use for a single I-7017.  The code is a little more complicated than the example code.  This code is much more robust that the example code and provides methods to allow the PLC to continue to function even if the I-7017 dies.

The Simulation RELAY is checked to see if I am running the code in simulation vs. real hardware.  The simulator doesn't simulate NETCMD$().  The ADCError is a RELAY that is set if the I-7017 quits responding or has not been successfully initiated.  I do not want my PLC to lock up polling dead hardware.  

I have a retry mechanism that will wait and resend the NETCMD$().  I found that this improved the reliability of the system tremendously.  I kept track of how many retries were required and it was less than 1 every week on my system.  The retry was much better than having the system fail once a week.

The for next loop at the end of the code extracts the ADC value for each channel and then scales it to enginerring values that are easier to read.  It's easy, even for my old brain, to read 370 and think that means 37.0 C. The scaling components are stored as a set of 3 integer values in DM.

Writing to the LCD was done on the next ladder scan.



' ReadAllADC - function to read, scale and format all 8 analog value from I-7000
'
IF (TestIO(Simulation) = 0) AND (TestIO(ADCError) = 0)
???' Read all available ADCs from a I-7000 device
???' NETCMD$ is used to send command and wait for response
???' using the suffix "~" to suppress the FCS computation

???I = 4?????????' Retry count
???W$ = NETCMD$(3,"#01"+CHR$(13)+"~")
???WHILE (LEN(W$)= 0) OR (ASC(W$,1)<> 62)
??????I = I - 1
??????IF (I = 0)
?????????SetIO ADCError : RETURN??????' Still not working
??????ENDIF

  ??????'   Retry command
??????'
??????DELAY 10
??????W$ = NETCMD$(3,"#01"+CHR$(13)+"~")  
???ENDWHILE

???' Extract all numerical digits from the response but omit the
???' decimal point. Each data fragment is represented as a percent of
???' the A/D fullscale (+100.00 to -100.00). Full scale input is 250mV.
???' "+xxx.yy" or "-xxx.yy".
???' Extracted integer integer data will be returned in DM[201] to DM[208]
???
???FOR I = 0 to 7
???   ???T = VAL(MID$(W$,2+I*7,4)+MID$(W$,7+I*7,2))  ' Get the digits w/o the period

??????' Scale the data to engineering units
??????'
??????T = T * DM[41+I*3]
??????IF (DM[42+I*3])
?????????T = T / DM[42+I*3]
??????ENDIF
??????T = T + DM[43+I*3]
 ???  ???DM[201+I] = T????????????????????????' Store Scaled result for this channel
???NEXT

ENDIF


[/color]

Gary D
« Last Edit: May 09, 2012, 09:29:13 PM by garysdickinson »

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #3 on: May 10, 2012, 09:55:13 AM »
Hi Gary, thanks for the response.
We are automating an irrigation system. The tank levels don't change quickly, but the flow sensors do. We are using flow sensors that output flow rate, and applying that rate over time to get flow volume. On the one hand we would like to scan the rate very often to capture abrupt changes in flow that occur when a valve opens and pipes fill, on the other hand converting rate to volume leads to a "rounding" error every time you do it so doing it less often reduces the rounding error. I guess if I'm taxing the PLC then that is another reason to scan less often.
I can convert the HMI to ladder logic, and I can implement your RETRY code for the 7017. You have suggested to stagger the 7017 readings. One way I can think to do this is to run the Clk1.0s and use a counter with an IF statement to run each one on a different second. In fact, I can split up the reading of all the other sensors too, so only 1/5th of the code runs per second. Is there a better way you can think of doing this?

In your description of the ADCError you say you, "do not want my PLC to lock up polling dead hardware." Do you mean waste time, or is it possible that the PLC will become unresponsive and stuck? Also, if that relay is tripped does your program stop trying to read from the 7017 for all future scans?

I have a Clk:1.0s that runs every time and others that run when in a particular State. Is it better for these to be on separate ladder rungs? I could combine them into one rung with TestIO for which state is active if that would avoid problems.

I'm hopping support will answer my question of what happens with multiple rungs of Clk:1.0s when the functions take longer than 1.0s to complete. Is the lower rung just skipped? Or does the program as a whole stop running in real-time while waiting for functions to finish? Or are certain rungs skipped depending on what time it is when an above rung completes the function? Any one of these will cause problems in the code I have, but if I know which one I can change the code to avoid problems.

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #4 on: May 10, 2012, 01:16:41 PM »
Running the HMI I/O as direct ladder rungs works great. No more lag in keystroke pickup.

After splitting up the code so that some things run on the first second of a 5-second cycle, and some on the 2nd second, 3rd second, etc. I was still not getting a read on the 7017s. I noticed one line of code in the sample code for the 7017 that I hadn't given much thought to. The first line of function 250 is "SetBaud" Comm 3 to 9600, which is what the 7017s are expecting. The default Baud rate for the RS232 and RS485 is 38400 for this PLC so adding this line to the 1st.Scan function is needed to properly communicate with the 7017s.

Is it likely that increasing the Baud Rate would allow me to go back to my original code where everything runs every second?

garysdickinson

  • Expert Member
  • Posts: 464
  • Old PLC Coder
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #5 on: May 10, 2012, 02:07:10 PM »
Travis,

I glad you are making such good progress.

The ladder logic snippet is how I make delayed versions of clocks. I just use a string of RELAYS to generate delayed version of the system clock. This way I can distribute CPU intensive stuff across different scans of the ladder code.

Changing the BAUD rate will reduce the time that is required to communicate with the I-7017, however it will have no affect on the amount of time that the I-7017 takes to respond to the request for data.  So speeding up the BAUD rate by 4X will not cut the time for the special function to 1/4.

The issue with polling dead hardware: if the I-7017 goes off-line because it dies, the RS-485 cable is gets un-plugged or any of several doomsday possibilities, is with the NETCMD$() function.

This function builds a string based on the arguments that you provide, packs this string into a buffer that transmits the characters out the serial port and then waits for something to reply to the message.  

If your I-7017 doesn't reply in a few seconds the NETCMD$() will timeout and return some sort of error status.  The amount of time that the NETCMD$() waits is not specified, but I've found that it will wait at least 3  seconds. Your special function will hang up until the NETCMD$() times out.  If you retry the NETCMD$() 10 times in a single special function, this code may take 30 seconds to complete (actually fail).

The idea with the ADCError was to set this RELAY if the I-7017 appears to go dead.  I post error messages to get someone to troubleshoot the problem.  The ADCError is also used by other code in the PLC program to do what ever I can to keep the system working safely without the use of the I-7017 data (limp-home mode for a car).

I set the ADCError on the 1st.Scan of the ladder logic and then initialize the serial port (set the baud rate) and initialize the I-7017.  If the I-7017 responds correctly after initialization, only then do I clear the ADCError RELAY.

Another approach to deciding how often to poll your flow sensors is to ask your self, "how accurate is the output of the sensors?". Don't be surprized if they are spec'd at +/- 5%.  The I-7017 will add some error.  You may pick up a little error with the integer math on the PLC. No matter how often you sample the input data, your results can never be more accurate than your raw data, the results will always be worse.  Just figure out how much uncertainty you and the customer can tolerate.

Gary D


« Last Edit: May 10, 2012, 02:36:11 PM by garysdickinson »

garysdickinson

  • Expert Member
  • Posts: 464
  • Old PLC Coder
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #6 on: May 10, 2012, 08:30:12 PM »
Travis,

In response to your question about approaches to make delayed clocks.  I've included another version of code that I have used in one of my PLC projects.

This version uses only a single COUNTER, but using the Sequencer mechanism that is available only to the first 8 counters in the PLC.  The other version used a RELAY for each state and chews up more of the PLC resources.

This version divides the incoming clock by 5.  Each output runs at 1/5 the input clock rate and each output is delayed in phase from each other by one input clock.

If you want a one second output clock, run this circuit from the 0.1sec contact and change the Set Value of Seq1 to 9 (divide by 10).


Gary D.
« Last Edit: May 10, 2012, 08:32:30 PM by garysdickinson »

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3118
    • View Profile
    • Internet Programmable PLCs
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #7 on: May 11, 2012, 09:13:55 AM »

I'm hoping support will answer my question of what happens with multiple rungs of Clk:1.0s when the functions take longer than 1.0s to complete. Is the lower rung just skipped? Or does the program as a whole stop running in real-time while waiting for functions to finish? Or are certain rungs skipped depending on what time it is when an above rung completes the function? Any one of these will cause problems in the code I have, but if I know which one I can change the code to avoid problems.

The system clock pulses themselves are interrupt-driven so for a 1 second clock pulse, first 0.5s the contact CLK:1.0s will be ON and next 0.5s it will be OFF and then repeatedly so.

If a rung of ladder that drives a custom function takes longer than 1 second to compute, then by the time it finishes and begin executing the next rung, it depends on whether at this point if the CLK:1.0s contact is ON or OFF. If it has already gone to OFF state then the next rung that uses the CLK:1.0s will not execute and the logic scan continue to the following rung.

If the next custom function must run after the current function has completed even if it has taken longer than 1 second to complete, then you should either parallel the next custom function coil to the same ladder rung driven by this CLK:1.0s contact, or you can "CALL" the next custom function.

For critical input signals you may connect them to interrupt inputs and use interrupt custom function to process them.

There is also a periodic timer interrupt which can be used to execute a custom function to process critical events at pre-determined time intervals, but be sure that the function execution time is shorter than the period between consecutive execution of the timer interrupt function.
« Last Edit: May 11, 2012, 09:30:41 AM by support »
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3118
    • View Profile
    • Internet Programmable PLCs
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #8 on: May 11, 2012, 09:35:11 AM »
Regarding flow rate and flow volume

What kind of output does your flow rate sensor produce? If your flow rate sensor produces a train of pulses and if you are using a Nano-10, FMD or F-series PLC you can feed the pulses to a High speed counter (HSCDEF) input channel which also simultaneously support PULSEFREQUENCY or PULSEPERIOD functions. This way you can obtain the instantaneous flow rate data using the frequency or period of incoming pulses and AT THE SAME TIME you get cumulative pulse counts from the HSCPV counter which gives you the total flow volume.
« Last Edit: May 11, 2012, 09:36:40 AM by support »
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #9 on: May 11, 2012, 10:11:59 AM »
I haven't learned how to use the built in coils for: counters, sequencers, timers, except for the Clk: ones that I'm using. I will learn what I need to, if I need to, but at the moment it appears that splitting up the actions into 5 different seconds of a 5 second cycle is doing the trick. Although, I'm not done writing the program, so I'm not out of the woods yet.
I would have to look more closely, but I don't think any of my functions can be skipped if one function takes too long to execute, so using an interrupt just moves the problem around.
My flow meters (and at this time all my sensors) are 4-20mA analog signal. I think this allows me to avoid leaning Pulse-* commands for now, as I can't use them with the sensors that are already bought.
However, I'm trying to read the output every 5 seconds and apply the observed flow rate to the previous 5 seconds to compute volume. If the PLC falls behind real time then I'm not calculating the flow volume correctly anymore. At that point it's better to go to a 10-second cycle giving each of the 5 parts 2 seconds to run, or have 10 parts at 1 ssecond each.
I think it's time to write a piece of code that compares the number of cycles to the number expected over a longer period of time. The weekend is coming up, a perfect time to test!

General questions about efficient coding:

Is it better to us "AND-OR" or to nest the IF statements?

If I have many "IF" statements that are normally false (testing for problems) do these statements get processed very fast?
The idea is to build a nested structure with the least likely "TRUE" test at the top, so that the least amount of the nested structure gets analyzed at any pass through. The downfall is that this will take more lines of code because I will have fewer nested IFs within each IF statement.
 (I should have paid more attention in school when they talked about efficent coding practices.  :(  )

My code is only 2000 lines so far, and I think the biggest limitation is reading over the RS485. If I find I still have problems with inefficient code I'll ask more questions about how to streamline what I'm trying to do. Thanks for all the help!
« Last Edit: May 11, 2012, 10:12:57 AM by TravisB »

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3118
    • View Profile
    • Internet Programmable PLCs
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #10 on: May 11, 2012, 10:35:34 AM »
Quote
 Is it better to us "AND-OR" or to nest the IF statements?

The fastest execution is in resolving the ladder logic (series or parallel rung). TBASIC statements takes longer to run. AND-OR might be quicker than nested IF statements.

However, generally statement execution time is seldom a problem unless you are filling up large amount of data memory or FRAM. Delay due to failed communication via RS232 or RS485 is a much bigger issue. When communicating with other devices the CPU need to send the command and wait for a response. The transmission time is determined by the baud rate. The device it communicates with may need some time to respond and during this time the CPU can only wait until it receives a proper response, or time out (default is 0.15s) if no response is received. The NETCMD$ by default retries two more times if it didn't receive a response. That means if the device fails to respond the CPU will waste 0.45s not getting anything else done. (You can change the number of retries and waiting time using the SETSYSTEM command)

So it is important that you test the communication routine first to make sure that you work out all the bugs in the communication code so that there is little delay in communication when the partnering device is active and have a mechanism to detect failure (as per Gary's suggestion) when the partnering device is not responding so that it does not become a drag on the total system performance.

To use your 4-20mA flow sensor to accurately compute the flow volume, you could setup a periodic interrupt to run a custom function every 5 seconds (5000 ms), read the analog input and compute the flow volume in the last 5 seconds and add to a variable that stores the cumulative volume. That should give you a very accurate flow volume readings regardless of execution time of the rest of the program.

Note: Periodic timer interrupt is not available to M-series PLCs. Nano-10, FMD and F-series PLCs all support the periodic timer interrupt.
« Last Edit: May 11, 2012, 10:37:37 AM by support »
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #11 on: May 11, 2012, 01:07:59 PM »
In Gary's code for talking to 7017s he has a re-try routine built in, I think it does 5  total commands of NETCMD$. If each NETCMD$ command already does 3 tries before stopping, then Gary's code will try 15 times before giving up for a total of 2+ seconds. I don't want this, and maybe will just rely on the built-in 3 attempts totaling 0.45s, but keep the part that stops trying to communicate once a 7017 times out from the default 3 attempts.

My problem with any interupt is that I'm reading flow sensors through the PLC and through 3 different 7017s. Reading the 7017s over the RS485 is one of my slow processes, which means it's the most likely to get interupted. For most of the other functions, if they are interupted it will result in incorrect calculation of total flow. The rest of your suggestion is what I'm already doing, reading flow once every 5 seconds and adding the volume to a total volume variable. As long as this occurrs every 5 seconds reliably, I'm calculating flow as I need to. (Pulse flow meters are much better for total flow, but that's not what the client wants!)

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #12 on: May 11, 2012, 03:29:36 PM »
Well, it didn't take long for the problem to be noticable. I set a counter which would increment within one of the functions  every 5 seconds. After about 30min it was more than 60 counts BEHIND what it should have been. Back to the drawing board.

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3118
    • View Profile
    • Internet Programmable PLCs
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #13 on: May 11, 2012, 03:29:50 PM »
So the flow sensors are connected to the I-7017 analog inputs and not the PLC's analog inputs? In that case you have to be able to read I-7017 reliably.  If your baud rate settings are correct and you allow some delays between commands you should be able to communicate with the I-7017 reliably. Note that you should allow some time delay before you switch from one I-7017 to another I-7017. It is better to read all the channels from one I-7017 and then switch to another I-7017 instead of reading one channel from each I-7017 and then the next channel.
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

TravisB

  • Newbie
  • Posts: 33
  • I am NOT a llama!
    • View Profile
Re:Program execution takes longer than Clk:1.0 Clock?
« Reply #14 on: May 11, 2012, 04:02:55 PM »
I have 18 flow sensors, so some are being read off the PLC (via AN20MA-2) and the rest off the 7017s, one of which is co-located with the PLC and the other two are some distance away on a different part of the property.
Communication with each 7017 happens during a different second, but other custom functions run during the same seconds as the 7017 communication. I've tried to space things out evenly, but it clearly isn't working at the moment.
I'm open to suggestions, including different PLC equipment or communication protocols. One thought I had: use an FMD88 to replace the 7017s. I could multidrop them just the same, but do some remote calculations and send the calibrated data, thus processing remotely and freeing up some processing space on the main F1616-BA.
Ideally I would handle the problem through more efficient code, but if it means scanning the sensors much less often then I want to have an alternate option for the client, one which would allow the high scan rate we originally discussed.

And in case I sound unappreciative, I want to once again thank support and Gary for all the help with this project. It?s been fun learning all this stuff and I'm considering automating and datalogging my own apartment!

Geeze ???, just ran another 30min test and this time the counter is where it should be, implying no lag. I'll let it run over the weekend and see how it does.