Setting OPx on based on IPx

TJF1960

Active Member
Looking for a little help please. This seems like a very simple question but I would like some suggestions.

If IP1 = 1 then set OP1 on, only once. To do this I came up with this:

TSTNE IP1 OP1
TSTEQ IP1 1 OP1

This one I need help with:

If IP1 = 0 then set OP1 off after 10 seconds, only once. Also I do not want the code to stop running while waiting for the 10 seconds. I would like to not use any VARx or RAMx if possible as they may be all used for other things as it is.

Thanks,
Tim
 
Looking for a little help please. This seems like a very simple question but I would like some suggestions.

If IP1 = 1 then set OP1 on, only once. To do this I came up with this:

TSTNE IP1 OP1
TSTEQ IP1 1 OP1

This one I need help with:

If IP1 = 0 then set OP1 off after 10 seconds, only once. Also I do not want the code to stop running while waiting for the 10 seconds. I would like to not use any VARx or RAMx if possible as they may be all used for other things as it is.

Insufficient information.

If input1 goes high *ONLY BRIEFLY* do you want to stretch it to 10 seconds, or terminate early?
If input1 goes high and STAYS HIGH making the output go high *only for the first 10 seconds* is fairly easy.
 
Sorry for the lack of info.

When IP1 goes high it will stay that way for at least an hour. Likewise when it goes low it will remain low for at least an hour.

Ultimately I would like:

When IP1 goes high I want OP1 to go high 2 seconds later and stay high until IP1 goes low.

When IP1 goes low I want OP1 to go low 10 seconds later and stay low until IP1 goes high.

Thanks,
Tim
 
Sorry for the lack of info.

When IP1 goes high it will stay that way for at least an hour. Likewise when it goes low it will remain low for at least an hour.

Ultimately I would like:

When IP1 goes high I want OP1 to go high 2 seconds later and stay high until IP1 goes low.

When IP1 goes low I want OP1 to go low 10 seconds later and stay low until IP1 goes high.

Untested, but without using any ram or var, can you give this a go? I *think* it'll work.

Code:
start
   tsteq ip1[2000] 1 op1
   nop
   tsteq ip1[10000] 0
   set op1 0
end

The logic being the test if ip1 is 1, set op1 high. The [2000] will void the test until ip1 has been 1 and stayed 1 for 2 seconds.
So if it goes high briefly, then goes low, it won't set op1, and it will only set op1 after 2 seconds of ip1 being=1
the nop is required for when the test passes and skips the next instruction.

tsteq ip1[10000] 0 tests for input1 to be stable for 10 seconds, AND equal to zero. (ie, the falling edge). When true, it will set op1 off.

These tests will both continue to set op1 to the required state after 2 or 10 seconds, meaning if something else in your code has to set or clear the output, it won't.
 
Thank you so much for pointing me in the right direction. I have learned quite a lot from all of you in this forum!
I had at one time tried the non-blocking delay but again had the same results. OP1 followed IP1 with no delays. I then found the thread by Lou Apo describing the operation http://cocoontech.co...delay-function/ (Thank you Lou). After trying to digest how it worked I tried:

start
tstne ip1[2000] 1 op1
nop
tstne ip1[10000] 0
set op1 0
end

The result was when IP1 was high OP1 was low, when IP1 was low OP1 was high. But I noticed when IP1 went low there was a delay of 10 seconds turning OP1 on! The long an short of it is reversing the OP1 output as follows:

start
tstne ip1[2000] 1
set op1 0
tstne ip1[10000] 0
set op1 1
end

This produces a 2 second delay after IP1 goes high in turning on OP1 and a 10 second delay after IP1 goes low in turning off OP1.
I still dont have my head wrapped around it but it is working so far.

Thanks again,
Tim
 
start
tstne ip1[2000] 1 op1
nop
tstne ip1[10000] 0
set op1 0
end
The result was when IP1 was high OP1 was low, when IP1 was low OP1 was high.

Out of interest, did you try the code I suggested?
The reason yours is inverted is because you use "tstne" (test if NOT equal), where I'd used "tsteq" (test if EQUAL).
I believe based on your comments, my code as posted should have worked.
 
rossw,

I set up a test condition on another board closer to my bench. I set up OP1 in place of IP1 and OP2 in place of OP1 so I could conduct the test using the web gui to turn on and off OP1and watch OP2 at the same time.

START
TSTEQ OP1[2000] 1 OP2
NOP
TSTEQ OP1[10000] 0
SET OP2 0
END

When OP1 goes high there is indeed a 2 second delay then OP2 turns on. But when OP1 is switched low OP2 goes low at about the same time (barely a second later). So the first part of the code works but the second half doesn't.

I believe the reason I did not have a 2 second delay on my application is due to switch bounce. I didn't give that another thought though because I believed as you do that once IP1 was high for 2 seconds it would switch OP1 high (in the original config.) so any switch bounce would not matter.

I have tried switching OP1 off at different intervals which doesn't seem to make any difference.

Still don't have my head wrapped around this feature. Am I doing something wrong?

Thanks,
Tim
 
Odd. So I dug out a board and tried it. There appears to be some sort of race condition, because both my code and yours work - sort-of, intermittently.
Yours with the tstne and inverted logic is less prone to it, but if you change inputs in less than the timeout, you can get strange results.

What version firmware are you using? I recall raising an issue with cai on the non-blocking timers some time ago, and was told it had been fixed in a later version of the code. I'm playing with 3.0.7 at the moment, but I think it was one with the problem... I'll go get a later version board and try again.
 
Ahh, yes, 31-July-2012 I reported the problem, and provided code to demonstrate it.
The reply from CAI:

> Hi Ross,
>
> This is fixed already in the current firmware. The non-blocking delay was
> not initialized correctly in the old firmware.

So there's a known problem for versions up to somewhere shortly before that time.
 
Hmm, from the other thread:

For example: TSTGT VAR1[500] 1

1) Check if var1 is greater than 1, just like normal.
2) Check to see the last time VAR1 changed value. If VAR1 changed within the previous 500ms, it will be false, even if both the old and new value were greater than 1. For example, VAR1 might have been at the value 100, then 200ms prior to the above line of code executing it change to 200, even though both are 100 and 200 are greater than 1, it still runs false.

Both 1 and 2 must be true for the statement to be true.

In the code:

tsteq ip1[2000] 1
set op1 1
tsteq ip1[10000] 0
set op1 0


the second test SHOULD evaluate "false" if ip1 has not been stable for the last 10 seconds - such as would happen with a transition - and as such, should not execute the "set op1 0" statement. Since this is the only place op1 gets set anything other than 1, it MUST be executing this instruction, somehow - so there's still an underlying fault either in the behavior OR in the description of the behavior, surely??
 
I just tried the correction to the code I made a couple of post back to my application and it didn't work like the test did...could be due to how webcontrol board handles IP vs OP in regards to non-block delay.

I also noticed on my application (using tstne) that if IP1 is low for a while, 20 or so seconds, then goes high OP1 goes high almost immediately. But turning op1 off always works with the 10 second delay.

Clearly I still don't understand this function fully
 
Back
Top