Different behaviors of an IF-statement
BlackLabel
Posts: 25
Hi!
Could anybody tell me the difference between these two lines of code?
I can activate/deactivate the coffee function from TP.
This is my code (it's now running properly):
In my first version, the IF-statemant was this:
The program did pass the IF several times (I had about seven beeps on the TP) - ignoring the the state of COFFEE_ACTIVE.
After changing the expression after the IF, the code following the IF will only be executed if BOTH conditions are true. (Only one beep on TP)
The program takes one byte more in the working version (compiled file size) than in the non-working version.
I did checked this several times, because I couldn't believe it.
I also checked the state on COFFEE_ACTIVE by directing the state to an unused relay.
I'd like to understand what's wrong in order to avoid further problems by using code like this.
Any explanation appreciated.
Many Thanks
BlackLabel
Could anybody tell me the difference between these two lines of code?
IF ((COFFEE_ACTIVE = 1) AND (TIME = ALARM_TIME)) <-- runs incorrect IF ((TIME = ALARM_TIME) AND (COFFEE_ACTIVE = 1)) <-- runs correctI've got an Axcent2;. A part of my program should start my coffee maker at a user setable time (ALARM_TIME), it also should print an info on my TP.
I can activate/deactivate the coffee function from TP.
This is my code (it's now running properly):
DEFINE_START COFFEE_ACTIVE = 0 PUSH[TP,217] (* "COFFEE_YES/NO" *) { COFFEE_ACTIVE = NOT(COFFEE_ACTIVE) } [b]IF ((TIME = ALARM_TIME) AND (COFFEE_ACTIVE = 1))[/b] { ON [RELAY,12] SEND_COMMAND TP,'WAKE' SEND_COMMAND TP,'PAGE-INFORMATIONS' SEND_COMMAND TP,'BEEP' SEND_COMMAND TP,"'!T',152,ALARM_TIME,$0D,'COFFEE MAKER STARTED...'" COFFEE_ACTIVE = 0 }
In my first version, the IF-statemant was this:
IF ((COFFEE_ACTIVE = 1) AND (TIME = ALARM_TIME))In this version, the IF became true when (TIME = ALARM_TIME) became true, regardless of the state of COFFEE_ACTIVE.
The program did pass the IF several times (I had about seven beeps on the TP) - ignoring the the state of COFFEE_ACTIVE.
After changing the expression after the IF, the code following the IF will only be executed if BOTH conditions are true. (Only one beep on TP)
The program takes one byte more in the working version (compiled file size) than in the non-working version.
I did checked this several times, because I couldn't believe it.
I also checked the state on COFFEE_ACTIVE by directing the state to an unused relay.
I'd like to understand what's wrong in order to avoid further problems by using code like this.
Any explanation appreciated.
Many Thanks
BlackLabel
0
Comments
I'm sorry, it's nothing special.
I'm just using an RF controlled AC outlet in my kitchen where the coffee maker is connected to.
The RF transmitter (4 channels) for the outlet is attached to four relays on my Axcent2.
The transmitter is sending the command for ON if the corresponding relay becomes closed and sends the OFF command if the relay opens.
If I like to get a automatic brewed coffee in the morning, I have to prepare the maker in the evening.
It's like a RF-X10 (also 1-way), but much more reliable.
The other three channels are used for controlling the lights.
Having a traditional programming background I can't stand for seeing = used as an equals test. Also, AND should be the same thing as &&, but I've always used the latter. Those are the only things I can think of.
if I change the code from single = into ==, I get an syntax error.
&& instead of AND is working, but the strange behavior still remains.
All my knowledge in AMX programming is self educated, so I'm happy that I found out how to make my code running.
Maybe it's a problem of my NetLinx.
I'm using
NetLinx Studio 2, Build 2.2.0.83
NetLinx Compiler Build 2.2.0.108
Axcess Compiler Build 2.0.0.143
My Axcent2 firmware is 3.600
I guess, the double equal operator (==) is allowed for the NetLinx language only.
true, == can only be used in Netlinx code.
btw, as far as i know, = is the same as == in Netlinx, it's just more fashionable to use == when testing a var against another...
Not quite. When it sees a single =, it figures out by context whether its an assignment or comparison. When it sees ==, it's always a comparison ... so there is the possibility of ambiguity if you just use the = for comparisons. Having said that, it would be very rare for that mistaken interpretation to happen, but it could.
But ... back to the original post ...
I think the problem has something to do with the internal precedence levels Axcess uses to process complex comparisons. I never did work it out completely - I generally just bowed to expediency and re-structured my code. In the case of the example, instead of fighting to make ((COFFEE_ACTIVE = 1) AND (TIME = ALARM_TIME)) work in a single line, I would just next one if inside the other, like this
But that doesn't answer the why of it, just makes it work.
I have been watching this thread with interest and agree with Dave. The keyword TIME is dynamic and does not play well in compound comparisons.
Consider this method as well: I usually assign TIME to a variable array before doing any complex comparisons.
BlackLabel, What happens when you swap the position of TIME in your original comparison?
Brian, I'll try out your suggestions later. I'll also check the TEMP_TIME.
Until now, I thought, the program is proceeding an AND statement step by step until the first parameter equals FALSE and ignores the rest of the statement because the the AND can't become true.
In my wrong working IF, the first parameter is false until I set in to 1 by pressing [TP,217], but it seems, the program doesn't care about the COFFEE_ACTIVE = 0 and goes thru the code following the IF.
BUT if the program follows the code, COFFEE_ACTIVE must become FALSE after the first passing, but I can hear about seven BEEPS instead of one BEEP, so I guess, the program passes the code because of an missinterpreted IF (COFFEE_ACTIVE)...
Jeff
This is the only code, I uploaded to my processor: --> Relay 12 closes if TEMP_TIME equals TIME regardless the state of COFFEE_ACTIVE
There is no possibility that COFFEE_ACTIVE could become TRUE in this code!
I also checked the nesting of IF (COFFEE_ACTIVE = 1) and IF (TIME = ALARM_TIME):
--> This code is running properly.
Either it's an issue of my processor or I have found a compiler bug.
Move your COFFEE_ACTIVE =0 above your on[relay,12] and see if it stops your beeping.
your suggestion sounds very interesting.
Unfortunately I'm not at home till Sunday evening, so I'll check this on Sunday or Monday and give a feedback.
Many thanks!
Have a nice weekend.
We have an Axcent2 as the hardware, correct? This means we are compiling in Axcess. What's the version of Studio? I know there were reported Axcess compiler bugs for older versions of Studio. The current version should be fine.
IF ((TIME = ALARM_TIME) AND (COFFEE_ACTIVE = 1)) (* <-- whole program compiled 10538 bytes - runs properly *)
IF ((COFFEE_ACTIVE = 1) AND (TIME = ALARM_TIME)) (* <-- whole program compiled 10537 bytes - doesn't run properly *)
IF ((TIME = ALARM_TIME) AND (COFFEE_ACTIVE)) (* <-- whole program compiled 10535 bytes - runs properly *)
IF ((COFFEE_ACTIVE) AND (TIME = ALARM_TIME)) (* <-- whole program compiled 10534 bytes - doesn't run properly *)
"runs properly" means, the program starts my coffee maker at destinated time when COFFEE_ACTIVE is set to TRUE only.
"doesn't run properly" means, the program starts my coffee maker at destinated time regardless of the state of COFFEE_ACTIVE.
I checked the state of COFFEE_ACTIVE by TP feedback and by assigning to an unused relay.
Brian,
I'm using
NetLinx Studio 2, Build 2.2.0.83
NetLinx Compiler Build 2.2.0.108
Axcess Compiler Build 2.0.0.143
My Axcent2 firmware is 3.600
It must be a compiler issue.
Regards
BlackLabel
I can see how this has been a time consuming problem to debug since you only get to test it once a day and then have to wait 24 hours to try it again.
A double equal to (==) will bring a syntax error.
There is no problem with the debugging, because I'm using a routine for setting the ALARM_TIME from the touch panel,
so I can set the ALARM_TIME to current system time + 1 minute and see, what happens.
As I wrote, the problem itself is solved, because I found out, that I have to avoid to set the part "(COFFEE_ACTIVE = 1)" on the first position of the AND statement.
I just want to understand, what's going wrong if I change the two parts of the AND statement.
AND means, that both conditions must be TRUE, but the wrong working code shows an behavior like an OR.
In my code, I prefer to set the "(COFFEE_ACTIVE = 1)" at first position, in order to improve the readability of the code, because it's the more important part for me.
Did you get a chance to try swaping the position of TIME and ALARM_TIME? This is the current version.
This is an axcent - not a rocket ship, so by the time all the send_commands are done and then you switch off coffee_active, it may well have re-entered the routine. Remember this routine is in mainline..
I haven't got a box to test for you, but, I would always 'lock out' the routine as the first thing before anthing else.
With feedback,
[touch,1] = coffee_active
is not the same as
coffee_active = [touch,1]
Therefore, the time statement (TIME = ALARM_TIME), in my opinion is the wrong way around.
Having said that, my eyes are dim, and I'll need a cup of your coffee_active in a minute...what time is it meant to go off?!
:-)
You're right, but my problem is that my processor is executing the code after the IF when COFFEE_ACTIVE is FALSE and the ALARM_TIME (set by the user) equals the system time (TIME).
The bad code passes the IF routine regardless the state of COFFEE_ACTIVE until TIME becomes different to ALARM_TIME (in the next second).
In the corrct running version of the code, all parameters are same except the positions of the two conditions of the IF ((condition1) AND (condition2)) are swapped.
If COFFEE_ACTIVE is condition1, the code fails, if COFFEE_ACTIVE is condition2 everything is fine.
The coffee maker becomes switched off either by pressing a button on TP or two hours after it's started (should be enough time to get up and have breakfast).