non-blocking delay on the input

CAI_Support

Senior Member
In real life, sometimes there are needs for having ignore certain short pulses, like switch debounce.
 
For example, if you design a traffic light, you want to have green traffic light for main street most the time, when a car came to the intersection  from the smaller street it should trigger traffic light to change.  However, sometimes the car from smaller street just stop then made right turn, by the time traffic light changed there was no car waiting any more, so that the traffic light don't really need to change.
 
If you could use non-blocking delay on the sensor input in the above case, the shorter trigger will be ignored. Simply have a line like:
 SET VAR1 IP1[5000] 
Any car from smaller street did not stop longer than 5 second will not cause traffic light to change.  That will help more cars flowing on the main street.
 
CAI_Support said:
In real life, sometimes there are needs for having ignore certain short pulses, like switch debounce.
 
For example, if you design a traffic light, you want to have green traffic light for main street most the time, when a car came to the intersection  from the smaller street it should trigger traffic light to change.  However, sometimes the car from smaller street just stop then made right turn, by the time traffic light changed there was no car waiting any more, so that the traffic light don't really need to change.
 
If you could use non-blocking delay on the sensor input in the above case, the shorter trigger will be ignored. Simply have a line like:
 SET VAR1 IP1[5000] 
Any car from smaller street did not stop longer than 5 second will not cause traffic light to change.  That will help more cars flowing on the main street.
 
I have TTL Input 2 set up to monitor the A/C power to our house. The WebControl Board is set up on a UPS system so
it runs for several hours even when power is out. However, I want to know if the power is out so I setup a simple input
to send me an email when the power goes out. 
 
I want to ignore short pulses on the input. The input is connected to a CY17 opto-isolator that in turn is driven by a small
wall wart. When the power goes out, the input goes high, indicating a power failure. What I've tried is the following, but
it does not seem to work. 
 
TSTEQ IP2[1000] 1 
CALLSUB PWRFAIL
.
.
.
 
I believe the above should call PWRFAIL when IP2 is HIGH for more than 1 sec (1000ms). The behavior I'm seeing is
that PWRFAIL gets called whenever IP2 goes high. If I pulse the input for say 250 ms, it still calls PWRFAIL. I've tried
setting this to longer values with the same result.
 
Am I doing something wrong ?   ( FW: 3.02.13 )
 
It seems like it should work.  Using a wall wart can screw things up because it has a bit of lag in power up and power down.  I would instead use a 120v relay for a more instant result to power up/down.
 
Here is how the non-blocking delay works.
 
CAI stores the value of outputs, variables, and digital inputs along with a time stamp.
 
When a non-blocking delay is used in a test statement, the following happens
 
1) Is the time stamp prior to the delay period?  If yes, it does step 2, if not, it is false, it makes no difference what the value is or was.
2) Is the statement true of false at present.
 
It is important to realize that something like this can happen.
 
tstgt var1[1000] 1
 
This statement will be false if var1 changed value in the previous 1000ms, no matter what the old value was.  It might have been 2 then changed to 3 500ms ago.  Both are greater than 1, but the statement will still be false.  The non-blocking delay requires that the value did not change during the previous [x]ms no matter what the values were/are to be true.
 
tbalon said:
I have TTL Input 2 set up to monitor the A/C power to our house. The WebControl Board is set up on a UPS system so
it runs for several hours even when power is out. However, I want to know if the power is out so I setup a simple input
to send me an email when the power goes out. 
 
I want to ignore short pulses on the input. The input is connected to a CY17 opto-isolator that in turn is driven by a small
wall wart. When the power goes out, the input goes high, indicating a power failure. What I've tried is the following, but
it does not seem to work. 
 
TSTEQ IP2[1000] 1 
CALLSUB PWRFAIL
.
.
.
 
I believe the above should call PWRFAIL when IP2 is HIGH for more than 1 sec (1000ms). The behavior I'm seeing is
that PWRFAIL gets called whenever IP2 goes high. If I pulse the input for say 250 ms, it still calls PWRFAIL. I've tried
setting this to longer values with the same result.
 
Am I doing something wrong ?   ( FW: 3.02.13 )
When input state changing from zero to one, what do you see on the browser screen for ip2, does it change immediately?
 
CAI_Support said:
When input state changing from zero to one, what do you see on the browser screen for ip2, does it change immediately?
 
I've done this using a simple momentary switch connected as well, same results so while there is some decay time for the wall wart, it still calls the subr immediately. 
I don't have web polling enabled, so I hit the refresh button. It does not change immediately. 
 
Lou Apo said:
It seems like it should work.  Using a wall wart can screw things up because it has a bit of lag in power up and power down.  I would instead use a 120v relay for a more instant result to power up/down.
 
Here is how the non-blocking delay works.
 
CAI stores the value of outputs, variables, rams, and digital inputs along with a time stamp.
 
When a non-blocking delay is used in a test statement, the following happens
 
1) Is the time stamp prior to the delay period?  If yes, it does step 2, if not, it is false, it makes no difference what the value is or was.
2) Is the statement true of false at present.
 
It is important to realize that something like this can happen.
 
tstgt var1[1000] 1
 
This statement will be false if var1 changed value in the previous 1000ms, no matter what the old value was.  It might have been 2 then changed to 3 500ms ago.  Both are greater than 1, but the statement will still be false.  The non-blocking delay requires that the value did not change during the previous [x]ms no matter what the values were/are to be true.
 
This makes sense, however in my case this is a TTL input. Only 0 or 1 no hi-z. 
 
tbalon said:
I've done this using a simple momentary switch connected as well, same results so while there is some decay time for the wall wart, it still calls the subr immediately. 
I don't have web polling enabled, so I hit the refresh button. It does not change immediately. 
Your delay is 1 second, from hitting the switch, then click to the  refresh, it might already passed the delay time. Could you make it 10 seconds delay and try again?
 
To see what is going on a bit easier, hook an LED bulb up to one of the outputs and add a line to your subroutine that turns the bulb on as well as send the email.  This will help de-bug.
 
Perhaps you can post the entire program.  Something else is going on.  TSTEQ IP2[1000] will be a false statement until IP2 has been on for one continuous second.  Perhaps the line before that is causing the issue or somehow the subroutine is being run from a different source line.
 
CAI_Support said:
Your delay is 1 second, from hitting the switch, then click to the  refresh, it might already passed the delay time. Could you make it 10 seconds delay and try again?
 
Ok, I've changed the code to use a 10 second delay and loaded the new program.
 
TSTEQ IP2[10000] 1 
CALLSUB PWRFAIL
 
I then viewed the inputs
IP2 is 0
 
I disconnect the wall wart which is driving the CNY-17 opto-coupler
 
I hit refresh every second
 
After about 3 seconds,  IP2 goes high. ( this is the decay time for the wall wart ) 
 
I plug the wall wart back in and hit refresh, IP2 is 0 ( almost immediate ) 
 
In the above case, as well with shorter delays, PWRFAIL is always called when the PLC detects IP2 going high (1) . 
 
Lou Apo said:
To see what is going on a bit easier, hook an LED bulb up to one of the outputs and add a line to your subroutine that turns the bulb on as well as send the email.  This will help de-bug.
 
Perhaps you can post the entire program.  Something else is going on.  TSTEQ IP2[1000] will be a false statement until IP2 has been on for one continuous second.  Perhaps the line before that is causing the issue or somehow the subroutine is being run from a different source line.
 
Here is the entire program. While I'm sure it could be optimized, written differently etc. etc. , I'm more concerned with why the delay doesn't appear to
be working properly. 
 
 
START    
SET RAM1 0    // flag to indicate email 1 sent
SET RAM2 0   // flag to indicate email 2 sent
 
LOOP:
TSTEQ IP2[1000] 1 RAM7    // has the power been off for more than one second ? 
CALLSUB PWRFAIL             // Yes, call power fail subr
BNZ RAM7 L1                      // No, then test if power is back on ( RAM7 0 )
SET RAM2 0                        //  Yes, then clear email sent flag for next time
L1:
TSTEQ IP1[500] 0 RAM8     // has sump pump been running for more than 500 ms ( switch debounce )
CALLSUB SUMP                 // yes, call sump subr
BNZ RAM8 L2                     // no, then check if its now off 
SET RAM1 0                       // and if so, clear the email sent flag for email 1
L2:
GOTO LOOP                      // continue doing this forever
 
 
SUMP:
BNZ RAM1 BYE1              // have we sent the EM1 message already ? 
SET RAM1 1                      // no, then set flag (ram1) indicating we are sending email
EMAIL EM1                       // send the email that the sump is running
BYE1:                               
RET    
 
PWRFAIL:
BNZ RAM2 BYE2             // have we sent the power fail email ? 
SET RAM2 1                     // no, then set flag indicating we are sending email
EMAIL EM2                      // send the power fail email
BYE2:
RET    
 
END   
 
As an aside, you don't need to set ram1 and ram2 to 0 at start up.  Those two lines can only ran at power up and ram values are always zero at power up.
 
Attach an led to output 1 and write this program
 
START
TSTEQ IP2[1000] 1
SET OP1 1
END
 
Use the 5v output on CAI to switch ip2 to high manually.  The led should turn on 1 second later.  If it doesn't, then something is wrong with non-blocking delay.  If that works properly, then there is something wrong with your program.  I don't see anything wrong at first glance, but your style is a little different than mine.
 
tbalon said:
 
Here is the entire program. While I'm sure it could be optimized, written differently etc. etc. , I'm more concerned with why the delay doesn't appear to
be working properly. 
 
What firmware revision?
I recall having some similar issues with a reasonably early version where nonblocking delays were erratic and unreliable, subsequently fixed by CAI.
If there isn't a code problem evident, and your input is doing what you think, this may explain it?
 
Lou Apo said:
As an aside, you don't need to set ram1 and ram2 to 0 at start up.  Those two lines can only ran at power up and ram values are always zero at power up.
 
Attach an led to output 1 and write this program
 
START
TSTEQ IP2[1000] 1
SET OP1 1
END
 
Use the 5v output on CAI to switch ip2 to high manually.  The led should turn on 1 second later.  If it doesn't, then something is wrong with non-blocking delay.  If that works properly, then there is something wrong with your program.  I don't see anything wrong at first glance, but your style is a little different than mine.
 
Using the LED off OP1 showed that the delay is indeed working as expected. 
 
I replaced EMAIL EM1 with SET OP1 1, and added a SET OP1 0 after the set RAM2 0  When I use the LED on the output I can see that it works as it should.
 
I believe my confusion with this has more to do with the EMAIL being sent.  Yahoo mail sometimes delivers the message immediately and sometimes it gets delayed. When testing this was causing confusion since I would get multiple messages... 
 
tbalon said:
Using the LED off OP1 showed that the delay is indeed working as expected. 
 
I replaced EMAIL EM1 with SET OP1 1, and added a SET OP1 0 after the set RAM2 0  When I use the LED on the output I can see that it works as it should.
 
I believe my confusion with this has more to do with the EMAIL being sent.  Yahoo mail sometimes delivers the message immediately and sometimes it gets delayed. When testing this was causing confusion since I would get multiple messages... 
 
That's why I suggested the led.  Email is very confusing because of its inconsistency.  
 
rossw said:
What firmware revision?
I recall having some similar issues with a reasonably early version where nonblocking delays were erratic and unreliable, subsequently fixed by CAI.
If there isn't a code problem evident, and your input is doing what you think, this may explain it?
 
FW: 3.02.13 
 
Back
Top