Help with CASE statement
Hello all,
I am trying to build a garden/lawn sprinkler timer. Yes, I know, probably cheaper and easier to just buy one.... After some trial and error, I simplified the idea to "let just make an alarm clock" (same idea, set the DS1302 real time clock, set a time to do something, stay on a certain length of time, turn off, etc) And, I will also admit, this project may never get completed enough to water the lawn, but everyone has to start with an idea and a problem to work to find a solution to! Ha ha!
I am using my original Propeller Professional Development Board with a Parallax 4x20 LCD hooked up to one of the servo headers, and using 4 of the buttons at the bottom of the PPDB as inputs. Currently I am using one of the LEDs on the board as my output (alarm clock on, zone on, etc.)
Ok, so back to the subject. I have a repeat loop in my MAIN object. At the end of the loop I have a CASE statement with four options (set zone/alarm time, set DS1302 time, all zones off, and run). It looks something like:
PUB Main
repeat
......
......
inKey := %1111 'Initialize inKey variable
inKey := INA[PushButton3..PushButton0] 'Get number (in binary).
if inKey <> PushButtonMask case inKey %0111: SetTimer 'Go to SetZone method %1011: SetTime 'Go to SetTime method %1101: AllZoneStop 'Go to AllZoneStop method
' %1110: Active := True 'Set Active variable to TRUE
' %1110: Run2 'Go to Run2 method, to set Active to TRUE
%1110: Active := 1 'Set Active variable to 1 (TRUE), 0=FALSE
My original plan was to use the variable ACTIVE as a flag, push the RUN button, ACTIVE gets set to TRUE and somewhere else in the code looks at Active and determines if the alarm clock is turned on or off. Later, if I wanted to turn the alarm clock off (or turn the garden timer off), I could set ACTIVE to FALSE, etc. The Active := True statement never seemed to work.
Elsewhere in the code I have:
If Active == True
....(turn on alarm, etc)
After this did not work, I added a few lines in my code to show the value of Active, I could see it never seemed to get set to TRUE. Here is that section of my code:
If Active == TRUE
LCD.str(string("+"))
elseif Active == FALSE
LCD.str(string("X"))
else
LCD.str(string("Q"))
And, after I could not get a response from viewing TRUE/FALSE, I added "Q" just to see if I could pull something/anything from what the variable was equal to.
Then, I though maybe I need to send this to a separate method, like the other CASE options, hence the "Run2", with basically the same Active := True statement. Again, this did not work.
Finally I just set Active := 1 when the button is pressed, and Active := 0 to turn the alarm off, and it worked.
I know, I know, trial and error if you ever saw it....
Having said all that, I am left with the simple question, why did my original thought of setting a flag to TRUE or FALSE not work?
If anyone has any input, I would appreciate it. Thank you in advance.
-Rob
Comments
P.S. I can see when I posted my question, the 3 additional lines shown below the CASE statement box are part of the statement, but are not being shown in the box because (I assume) the ' mark to remark them out of the code.
@RobertW
False is 0
True is -1 (ie $FFFF_FFFF) or in fact, any value other than 0.
But I suspect your problem is in reading the push buttons. You need to debounce them so the code is probably setting and resetting many times.
You could just try and read one push button and output continuously the +/x and then push the button (and hold it pushed) and see the results, then release the button and see the results. You should see the characters toggle but you will likely miss seeing the bounce as it's qquite fast.
IN
@Cluso99
Thank you for your reply. Yes, I read in the Propeller Manual that TRUE is not truly "1", and it is really -1, but I reasoned, probably in error, what difference does it make if I am setting a variable to TRUE, then trying to determine later in the code if the variable is equal to (the same) TRUE?
If I declare my variable as a Byte sized variable, would this cause an issue if TRUE/FALSE are likely Long sized values?
And yes, as things were not turning out as expected, the thought about debouncing the button crossed my mind also. I will add that into my code also.
Thank you for your reply.
Never compare with true/false, it's just wrong and unneccessary. just use IF and IFNOT.
Yes, this is likely your problem. If your Active variable is a byte, then "Active := TRUE" will set Active to $FF (8 bits worth of 1's), but then "Active == TRUE" will be comparing $FF (255) with $FFFFFFFF (-1) and seeing that they are different.
As @Wuerfel_21 said, the best bet is just to say "IF Active" rather than "IF Active == TRUE".
@Wuerfel_21 and @ersmith thank you for your replies and comments. At first I did not understand @Wuerfel_21 's reply but I see what you are saying now. Check using "If Active", since Active would already be set to true or false. The "==True" or "==False" is implied in the statement.
I corrected the true/false issues, and also made the Active variable a long length, and as best as I can tell, everything is working properly.
Thank you for your help.
-RobW