Shop OBEX P1 Docs P2 Docs Learn Events
Need help with memsic sensor code. — Parallax Forums

Need help with memsic sensor code.

SN96SN96 Posts: 318
edited 2005-11-18 02:43 in BASIC Stamp
I was looking at this code and it all makes perfect sence except one variable "moTimer". In the code, in the main routine, moTimer is reset to zero, if moTimer is less than AlarmLevel. AlarmLevel is a constant set to 5, so how can moTimer ever be grater than 5 if it is reset to zero? What am·I over looking?

' =========================================================================
'
'   File...... MEMSIC2125-Motion.BS2
'   Purpose... Detects continuous motion for given period
'   Author.... Parallax (based on code by A. Chaturvedi of Memsic)
'   E-mail.... [url=mailto:support@parallax.com]support@parallax.com[/url]
'   Started...
'   Updated... 15 JAN 2003
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================

' -----[noparse][[/noparse] Program Description ]---------------------------------------------
'
' Monitors X and Y inputs from Memsic 2125 and will trigger alarm if
' continuous motion is detected beyond the threshold period.

' -----[noparse][[/noparse] I/O Definitions ]-------------------------------------------------
Xin             PIN     8                       ' X pulse input
Yin             PIN     9                       ' Y pulse input
ResetLED        PIN     10                      ' reset LED
AlarmLED        PIN     11                      ' alarm LED

' -----[noparse][[/noparse] Constants ]-------------------------------------------------------
HiPulse         CON     1                       ' measure high-going pulse
LoPulse         CON     0
SampleDelay     CON     500                     ' 0.5 sec
AlarmLevel      CON     5                       ' 5 x SampleDelay
XLimit          CON     5                       ' x motion max
YLimit          CON     5                       ' y motion max

' -----[noparse][[/noparse] Variables ]-------------------------------------------------------
xCal            VAR     Word                    ' x calibration value
yCal            VAR     Word                    ' y calibration value
xMove           VAR     Word                    ' x sample
yMove           VAR     Word                    ' y sample
xDiff           VAR     Word                    ' x axis difference
yDiff           VAR     Word                    ' y axis difference
moTimer         VAR     Word                    ' motion timer

' -----[noparse][[/noparse] Initialization ]--------------------------------------------------
Initialize:
  LOW AlarmLED                                  ' alarm off
  moTimer = 0                                   ' clear motion timer
Read_Cal_Values:
  PULSIN Xin, HiPulse, xCal                     ' read calibration values
  PULSIN Yin, HiPulse, yCal
  xCal = xCal / 10                              ' filter for noise & temp
  yCal = yCal / 10
  HIGH ResetLED                                 ' show reset complete
  PAUSE 1000
  LOW ResetLED

' -----[noparse][[/noparse] Program Code ]----------------------------------------------------
Main:
  DO
    GOSUB Get_Data                              ' read inputs
    xDiff = ABS (xMove - xCal)                  ' check for motion
    yDiff = ABS (yMove - yCal)
    IF (xDiff > XLimit) OR (yDiff > YLimit) THEN
      moTimer = moTimer + 1                     ' update motion timer
      IF (moTimer > AlarmLevel) THEN Alarm_On
    ELSE
      moTimer = 0                               ' clear motion timer
    ENDIF
  LOOP
  END

' -----[noparse][[/noparse] Subroutines ]-----------------------------------------------------
' Sample and filter inputs
Get_Data:
  PULSIN Xin, HiPulse, xMove                    ' take first reading
  PULSIN Yin, HiPulse, yMove
  xMove = xMove / 10                            ' filter for noise & temp
  yMove = yMove / 10
  PAUSE SampleDelay
  RETURN

' Blink Alarm LED
' -- will run until BASIC Stamp is reset
Alarm_On:
  DO
    TOGGLE AlarmLED                             ' blink alarm LED
    PAUSE 250
  LOOP    


Thanks

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Mike


"Don't always think outside the box, sometimes thinking inside the box is more practical and simple."
·

Comments

  • Bruce BatesBruce Bates Posts: 3,045
    edited 2005-11-17 16:06
    Mike -

    I didn't go through the program logic, but did you miss this line of code:

    IF (xDiff > XLimit) OR (yDiff > YLimit) THEN
    moTimer = moTimer + 1

    There is also an implied AND (I believe) once you reach the subsequent IF statement, listed below:

    IF (moTimer > AlarmLevel) THEN Alarm_On

    Additionally, every ELSE is "connected" ONLY with the immediately prior IF (unless PBASIC does something non-standard). Ergo, if BOTH conditions (implied AND noted above) are NOT met, THEN and ONLY then will:

    moTimer = 0

    Regards,

    Bruce Bates
  • SN96SN96 Posts: 318
    edited 2005-11-17 17:02
    This is how I read it:

    IF (xDiff > XLimit) OR (yDiff > YLimit) THEN ADD 1 to moTimer, but only add 1 if eirther condidion is met (OR), not both.

    If xDiff or yDiff are with in limits, moTimer will = 0. Even if moTimer had a value 1,2,3 or 4, the ELSE statement would make moTimer = 0.

    moTimer can only increment in value if xDiff or yDiff are grater than the limit values.

    I’m not saying I'm right, I'm just explaining my interpretation of the code. This is how it works in my mind when I read it.

    Please forgive my ignorance.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Mike


    "Don't always think outside the box, sometimes thinking inside the box is more practical and simple."
    ·
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2005-11-17 20:32
    Mike,

    ·· You are correct.· If either limit is exceeded, a counter (moTimer) will increase until it reaches the alarm level, at which point an LED will blink.· At this point you would need to reset the BASIC Stamp.· If, however, the device is back within limits before the counter reaches alarm level, moTimer is reset (It's not cumulative).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Tom WalkerTom Walker Posts: 509
    edited 2005-11-17 20:58
    SN96,
    FWIW, the "OR" evaluates to True if either OR BOTH conditions are true. The comparison you referred to (if either BUT NOT both) is "XOR" (exclusive OR).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2005-11-17 21:10
    Thanks Tom, I didn't cover that aspect of it.· You could, of course use AND, which would force both conditions to be met.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SN96SN96 Posts: 318
    edited 2005-11-17 21:13
    My mistake, I meant to say either one or both conditions met would provide a true condition.

    I still don't understand how moTimer can increase in value if the·ELSE statement tells it to reset to 0.

    I understand the code is correct, i just don’t understand the logics.

    Thanks for trying to explain. I will figure this out on my own.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Mike


    "Don't always think outside the box, sometimes thinking inside the box is more practical and simple."
    ·
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2005-11-17 21:54
    Okay,

    ·· You are testing a condition.· While this condition is true the moTimer variable is updated.· When the condition is NOT TRUE (FALSE) then the code below ELSE is executed.

    It's like, "IF THIS HAPPENS, THEN DO THIS OR ELSE DO THIS OTHER THING..."

    So one or the other will be executed depending on whether or not the result of the operation was TRUE or FALSE.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SN96SN96 Posts: 318
    edited 2005-11-17 23:18
    Chris Savage (Parallax) said...

    Okay,

    ·· You are testing a condition.· While this condition is true the moTimer variable is updated.· When the condition is NOT TRUE (FALSE) then the code below ELSE is executed.

    It's like, "IF THIS HAPPENS, THEN DO THIS OR ELSE DO THIS OTHER THING..."

    So one or the other will be executed depending on whether or not the result of the operation was TRUE or FALSE.

    Ok, I know you, and possibly everyone else on this forum would love to slap me but I still see the logic this way:

    Main:
    · DO
    ··· GOSUB Get_Data····························· ' read inputs
    ··· xDiff = ABS (xMove - xCal)················· ' check for motion
    ··· yDiff = ABS (yMove - yCal)
    ··· IF (xDiff > XLimit) OR (yDiff > YLimit) THEN·· 'if one or the other·or both is TRUE then add 1 to moTime
    ····· moTimer = moTimer + 1
    ····· IF (moTimer > AlarmLevel) THEN Alarm_On· 'if moTimer > 5 then·do Alarm_On·- otherwise moTimer = 0
    ··· ELSE
    ····· moTimer·= 0·' clear motion timer····'<-- When this is executed,·moTimer went·from 1 to··0
    ··· ENDIF
    · LOOP '<-- Do the cycle all over again with moTimer = 0
    · END

    So the above code looks as though moTime would flip flop from 1 to 0 to 1 to 0 all day long. The only way I can see it working is if the ELSE statement is not executed in a FALSE condition, keeping the value moTimer·equal to·1, then 2, then 3, untill it reaches 5 at which time Alarm_On would be executed.

    Sorry for the head ache guys. I know I am being a real pain in the @#$!




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Mike


    "Don't always think outside the box, sometimes thinking inside the box is more practical and simple."
    ·
  • Ryan ClarkeRyan Clarke Posts: 738
    edited 2005-11-18 00:13
    The only way that will flip flop is if one of the conditions xDiff > XLimit or yDiff > YLimit-
    and then they are not met following that (so the timer gets cleared)

    If neither of those conditions are met, then the moTimer will stay 0.

    Ryan

    Corrected 'clear' condition- thanks Jon, was thinking ahead of my fingers...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ryan Clarke
    Parallax Tech Support

    RClarke@Parallax.com

    Post Edited (Ryan Clarke (Parallax)) : 11/18/2005 12:22:52 AM GMT
  • Ryan ClarkeRyan Clarke Posts: 738
    edited 2005-11-18 00:16
    I would suggest writing a flow chart for yourself if you still don't understand what is going on, so you can trace through the flow of the code for yourself...

    Ryan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ryan Clarke
    Parallax Tech Support

    RClarke@Parallax.com
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-11-18 00:19
    Nope, that's not the case -- you're really making it much more complicated than it is. In SIMPLE terms, if there is motion on either (remember, OR is being used) axis then moTimer gets incrmented; if the device is perfectly still THEN moTimer is cleared. If moTimer exceeds AlarmLevel the alarm is tripped. This is a simple motion sensor program that makes sure the device is really moving before tripping the alarm -- think of it as debouncing, execpt, it's making sure that it is in fact bouncing (moving).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • SN96SN96 Posts: 318
    edited 2005-11-18 02:43
    Ok guys, thanks for all your help. I hope I did not cause you to pull to many hairs out of your heads. My wife is a programmer, and I showed her my problem. She pointed out where I was making my mistake this whole time.

    My error in following the logic was not realizing the ELSE statement belonged to the:

    "IF (xDiff > XLimit) OR (yDiff > YLimit) THEN moTimer = moTimer + 1 " line of code.

    I was originally reading it that the ELSE command belonged to:

    "IF (moTimer > AlarmLevel) THEN Alarm_On " line of code.

    She told me to pay attention to the indentation of the commands to follow the code, something I forgot to do. It all makes sense now. Champaign anyone?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Mike


    "Don't always think outside the box, sometimes thinking inside the box is more practical and simple."
    ·
Sign In or Register to comment.