Seeking solution to add time counters on IF /THEN or CASE statements
Nauketec
Posts: 51
Howdy All,
I have a sonar sensor that returns a measurement called "sonarRange"
It then gets checked against some IF/THEN/ELSE statements to determine what zone the subject is in and direct the program to GOTO a particular "mode".
The measurement·ranges are called:
Max_Range (greater than 20 feet ter)
Mid_Range (equal to or less than 20 feet
Opt_Range (equal to or less than 5 feet)
Min_Range (equal to or less than 4 inches)
The modes are:
mode1· no subject detected - Breathing
mode2· Subject detected - Wake-Up
mode3· Subject in Mid_Range
mode4· Subject in Opt_Range
mode5· Only after subject is in Opt_Range for desired time
mode6· Subject· in Min_Range - too close
The logic is working fine but what is missing is:
·timer/counter
IF·the subject is in the Opt_Range (mode4) for "T2" amount of time·(10 to 30 seconds)THEN GOTO mode5.
IF subject moves forward to range for mode6 or backwards to range for mode3 and then returns to the range for mode4 the program would goto mode4, the timer/counter would reset. It would· GOTO mode5 only after "T2"·amount of time is reached again.
This is my existing code:
IF· sonarRange > Max_range THEN
··· GOTO mode1 'Breathing"
· ELSEIF ((sonarRange =< Max_range)AND( sonarRange >= Opt_Range)AND(Last_Mode =< Current_mode2))THEN
··· GOTO mode2 'wake up
· ELSEIF ((sonarRange =< Max_range)AND( sonarRange >= Opt_Range)AND(Last_Mode > Current_mode2))THEN
··· GOTO mode3 'wake up
· ELSEIF ((sonarRange < Opt_Range)AND( sonarRange >=Min_Range))THEN
··· GOTO mode4· 'opt range
· ELSEIF sonarRange < Min_Range THEN
··· GOTO mode6· 'too close
· ELSE
··· GOTO mode0 'Diagnostics
ENDIF
·GOTO GeTMax_Range
Please use comments so I can understand it clearly.· I am a newbie and under an extreme deadline to get this working.
Thanks
Daniel
Post Edited (Nauketec) : 8/27/2008 4:37:20 PM GMT
I have a sonar sensor that returns a measurement called "sonarRange"
It then gets checked against some IF/THEN/ELSE statements to determine what zone the subject is in and direct the program to GOTO a particular "mode".
The measurement·ranges are called:
Max_Range (greater than 20 feet ter)
Mid_Range (equal to or less than 20 feet
Opt_Range (equal to or less than 5 feet)
Min_Range (equal to or less than 4 inches)
The modes are:
mode1· no subject detected - Breathing
mode2· Subject detected - Wake-Up
mode3· Subject in Mid_Range
mode4· Subject in Opt_Range
mode5· Only after subject is in Opt_Range for desired time
mode6· Subject· in Min_Range - too close
The logic is working fine but what is missing is:
·timer/counter
IF·the subject is in the Opt_Range (mode4) for "T2" amount of time·(10 to 30 seconds)THEN GOTO mode5.
IF subject moves forward to range for mode6 or backwards to range for mode3 and then returns to the range for mode4 the program would goto mode4, the timer/counter would reset. It would· GOTO mode5 only after "T2"·amount of time is reached again.
This is my existing code:
IF· sonarRange > Max_range THEN
··· GOTO mode1 'Breathing"
· ELSEIF ((sonarRange =< Max_range)AND( sonarRange >= Opt_Range)AND(Last_Mode =< Current_mode2))THEN
··· GOTO mode2 'wake up
· ELSEIF ((sonarRange =< Max_range)AND( sonarRange >= Opt_Range)AND(Last_Mode > Current_mode2))THEN
··· GOTO mode3 'wake up
· ELSEIF ((sonarRange < Opt_Range)AND( sonarRange >=Min_Range))THEN
··· GOTO mode4· 'opt range
· ELSEIF sonarRange < Min_Range THEN
··· GOTO mode6· 'too close
· ELSE
··· GOTO mode0 'Diagnostics
ENDIF
·GOTO GeTMax_Range
Please use comments so I can understand it clearly.· I am a newbie and under an extreme deadline to get this working.
Thanks
Daniel
Post Edited (Nauketec) : 8/27/2008 4:37:20 PM GMT
Comments
In any case, to pick up from http://forums.parallax.com/showthread.php?p=745020, to say "it doesn't work" or it "just gets stuck" doesn't give us much to go on. The example state machine with counters, did you understand it? The pieces? What it is supposed to do or not do? If you understand the basic concept, then tweaking it or tuning it or changing the decision logic shouldn't be too difficult. If the concept is hazy then maybe a different approach is order.
My suggestion at this point is tradeoff some responsiveness for ease of time programming on your end -- a state machine is nice because it can *keep checking* the sonar ranging, countdown timers, thresholds, whatever, and respond as needed. If you can trade off some of that responsiveness, then I would just put a pause with a do:loop into your actual modes when you want that mode to run for a set period of time. The main program will drop down to that mode, and just stay there till it's done. Changes in the sonar, swtiches, etc, won't be dealt with until the mode is done and control returns back to the main program.
You could probably do this without a statemachine if your sensor input and outputs were subroutines that could be called from any place in your program at any time, but you declined my suggestion to do so. And at risk of being repetitive, niceties like PIN definitions (names), and the like would make the program much easier to read and to follow. I don't see a current copy of your program in this thread, so I'm just using the snippet you provided. I'm also presuming you are using the sonar averaging? If so then I am estimating that you will get through your main loop no more than 3 or 4 times per second.
Now if you want the mode to run for a certain time based on sensor input (like mode5, I think, where the person has to be in a certain range for a certain amount of time, aka "hits") then simple state machine I posted in the other thread is about as simple as *I* can make it. You can eliminate all the counters for states that don't need them. A word size counter on "how many times in range" will give you around 15,000 seconds of time (I'm estimating) that you could count. The state machine in my example is your exact same IF/THEN/ELSEIFs but broken into separate statements -- the ELSE/ELSEIF part, i.e., the next state, requires TWO things to happen for it to kick in -- the sonar range needs to be right, as in your code above, AND the counter needs to have gotten to whatever count YOU decide. So if it takes 100 counts of the person in the optimum range before the next one kicks in, and that's about 25 seconds, you're set. But maybe it needs to be a count of 200 or 10. You'll have to test it.
Think of it like this:
Now the example above doesn't show resetting the counters for the "next" time, for clarity (see my earlier longer example). You may like this kind of if/then/else format better, but it's a bit limiting and you can work yourself into a dead end, but hopefully this makes sense.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 8/27/2008 5:29:41 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Thanks for the tip about threads - I just thought that if there were others that wanted to follow a topic, this way they would not have to pour through all the posts about averaging or whatever.
About the "fat" in my program - my thoughts as a newbie are to write the code and get it to work in a way I can monitor it easily and then at the end when I know it all works, compress it down by removing the all extra lines of code. That is why the debugs were there for so long - How else would I know if it is working? anyway - it is almost complete and now the next task is to create a means that when a subject is in mode4 for an amount of time it will go to mode5 and stay there as long as the subject is in that range. If the subject moves to the range of mode6 or back to mode3 and then re-enters the range for mode4 the timer resets and begins counting again.
Once this is done then I might be able to breathe better and try to better understand and use the State Engine. But until then unless someone is willing to write all this code for me for free or for fee, I must can only depend on me to get it done and I think is is always wise to go with what you know first. Even if this is "Bit Banging" it gets the job done and gets it done in a way I can understand it and, if need be, fix or change it.
So I will try your second suggestion first and then report back once I get it to work then we can discuss how to make it more clean.
Thanks again for all your help it has been a real learning by fire experiance!
Daniel
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
You have been a great asset so please continue!
Daniel
But, I have a suggestion -- put away your main and slave program for an afternoon.
Make a simple if/then/else tree with counters as has been outlined, but instead of any sonar or switch INPUT use DEBUGIN. Instead of any output, use DEBUG. You won't need any pins, any routines, only a few variables. Try out some routines and watch what happens on screen... enter your "input" on each loop and watch what happens. Experiment. Get the code working then break it. Then revisit your main program with fresh eyes.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I got it all to work now I am just doing a little burn-in test to see if there are bugs.
I only have one more small task on the LED micro and the program is DONE!
Thanks
Daniel