Variable Non-Blocking Delay

mazeeff

Member
I would like to have a variable non-blocking delay controlled by UROM4. ie.
 
SET OP2[UROM4] 1
 
The PLC takes the code without error, but a code refresh shows;
 
SET OP2 1
 
If I use;
 
SET OP2[180000] 1
 
Everything works fine, and I get the expected three minute delay. The fact that the PLC generates no coding error on the first example, leaves the programmer with the understanding that all is well, until OP2 turns on for infinity!.Is this a bug? Am I doing something wrong? How might I program a UROMx variable non-blocking delay using UROM4? The problem exhibits itself on both 3.02.13 and 3.02.17 boards.
 
OK. I will program a loop variable controlled by UROM4. Each pass through the loop can output OP2 for 60000 units (1 minute). If UROM4 is 5, I should get 5 minutes of output.
 
mazeeff said:
OK. I will program a loop variable controlled by UROM4. Each pass through the loop can output OP2 for 60000 units (1 minute). If UROM4 is 5, I should get 5 minutes of output.
 
Check your logic. Not sure it'll do what you think.
If you turn the output on, then do non-blocking delay for 60,000ms the first one will work....
... but second and subsequent times through the loop will be instant, as the change is already more than 60,000ms!
 
Another option would be to turn on the output, set a RAM/VAR to  (cts+UROM4), then compare CTS to that value.
You achieve the non-blocking delay (but only with 1 second resolution), and can specify time in seconds in your urom.
 
rossw said:
Check your logic. Not sure it'll do what you think.
If you turn the output on, then do non-blocking delay for 60,000ms the first one will work....
... but second and subsequent times through the loop will be instant, as the change is already more than 60,000ms!
 
Another option would be to turn on the output, set a RAM/VAR to  (cts+UROM4), then compare CTS to that value.
You achieve the non-blocking delay (but only with 1 second resolution), and can specify time in seconds in your urom.
 
Agreed. I would have to wait until the output times out, and then loop. I like your idea better, and will give it a try. Do I need to worry about CTS hitting its max value, and rolling over to zero? Thanks,
 
mazeeff said:
Agreed. I would have to wait until the output times out, and then loop. I like your idea better, and will give it a try. Do I need to worry about CTS hitting its max value, and rolling over to zero? Thanks,
 
cts is a 32-bit value, starting from what, 2000.  2^32 seconds is a little over 130 years, so it'll overflow around 2135. If that poses you a problem, then find another solution :)
 
rossw said:
cts is a 32-bit value, starting from what, 2000.  2^32 seconds is a little over 130 years, so it'll overflow around 2135. If that poses you a problem, then find another solution :)
 
I can live with that!!!
 
The CTS command worked great, but now I need more UROM locations. With each of the four UROM locations being 32 bits, it would be nice to use each one as two 16 bit numbers. Most of what I would store in UROM would be less than 2 to the 16th. Any ideas on how to provide more UROM variables or web variables?
 
You could store multiple values as a single urom.
 
For example, you might want to store 1235 and 4352
 
Set urom for 12354352.  Then in your code, whenever you need the first part of the number, divide by 10000.  That will truncate the last 4 digits.
 
When you need the final 4 digits, use the remainder function dividing by 10000 and that will give you the 4352.
 
You can temporarily hold these values as RAM variables until whatever subroutine is using them no longer needs them.
 
As long as you don't need anything bigger than 4 digits for each number this works.  You only get 9 complete digits on a signed 32 bit value since the 10'th digit doesn't have the full 0-9 range (only get 0,1,2).
 
Lou Apo said:
You could store multiple values as a single urom.
 
For example, you might want to store 1235 and 4352
 
Set urom for 12354352.  Then in your code, whenever you need the first part of the number, divide by 10000.  That will truncate the last 4 digits.
 
When you need the final 4 digits, use the remainder function dividing by 10000 and that will give you the 4352.
 
You can temporarily hold these values as RAM variables until whatever subroutine is using them no longer needs them.
 
As long as you don't need anything bigger than 4 digits for each number this works.  You only get 9 complete digits on a signed 32 bit value since the 10'th digit doesn't have the full 0-9 range (only get 0,1,2).
 
 Good idea. I can make this work. Most of what I store in UROM is less than 100. It would sure be nice to have a user option to turn each UROM variable into a 1x32, 2x16,  or 4x8
 
With the newer firmware you have the ANDB ORB XORB options which will allow you easier manipulation of individual bits.
 
todster said:
With the newer firmware you have the ANDB ORB XORB options which will allow you easier manipulation of individual bits.
 
Yes, no matter what you will need the new firmware.  The remainder function is also only on the new firmware.  The bitwise approach is also going to work, but it is too confusing for me. :blink:
 
AND, OR XOR was the whole variable operation, for example, if VAR1 is 1234 that is considered non-zero, if that is AND with VAR2, say its value is 5678, the result number is 1, because from whole number point of view 1 AND 1 = 1.
 
ANDB is different.  Same VAR1 1234 in binary mode is 10011010010, you can use Microsoft windows calculator in programmer mode to do the number conversion.
VAR2 5678 in binary mode is 1011000101110.  ANDB of those two number will get
0010011010010
1011000101110
ANDB
0010000000010
The advantage of bitwise operator is that you can use one VAR or RAM for up to 31 flags.  Each bit position can be used as one flag.
 
Back
Top