LowPowerLab Forum

Hardware support => Moteino => Topic started by: JonM on May 05, 2017, 11:24:34 PM

Title: ShockTest.ino question
Post by: JonM on May 05, 2017, 11:24:34 PM
I decided to download and give the ShockTest.ino a try:
https://lowpowerlab.com/forum/moteino/power-consumption-and-rfm69hw-help-needed/msg7288/#msg7288

And my question: why is there a countdown of "integral" from "SHOCK_THRESHOLD" down to zero?  I feel like I'm missing something important!

Details
I'm having trouble figuring out a part of the logic in the program.  It's not the developer, it's me - I'm too new at this.  I saw the note about this not being tested.

For the most part my ShockTest.ino is the same except for:
• pinMode from INPUT PULLUP to INPUT
• attachInterrupt from FALLING to RISING
• define SHOCK SAMPLE_TIME          500
• define SHOCK THRESHOLD            3
• define SHOCK ZERO THRESHOLD   10              // 10 * 500mS = 5 sec)
• and I've added a zillion DEBUG lines to help me understand.

So when the program is running and after there is no shock movement and after the "integral" equals "SHOCK_THRESHOLD":

if (integral >= SHOCK_THRESHOLD)
{
  rc = 1;   // say that we've exceeded the count
  integral = SHOCK_THRESHOLD;   // saturate at this high value
} else

Then there is a countdown and a count-up that needs to happen for the Arduino to go to sleep via "LowPower.powerDown".  The first is the countdown the "integral" variable.  Once it hits zero then that starts the "numZeros" count-up.

if (integral <= 0)
      {
        integral = 0;  // 'saturate' at zero
        numZeros++;
        if (numZeros >= SHOCK_ZERO_THRESHOLD)  // have we had enough sequential zeros to sleep?
        {
          rc=-1;  // yup, tell the caller...
          numZeros = SHOCK_ZERO_THRESHOLD;    // saturate value

Log of output at Line 109:

Motion - Do stuff
L109   detectedNumber: 0   integral: 3   rc: 0   numZeros: 0
L109   detectedNumber: 0   integral: 2   rc: 0   numZeros: 0
L109   detectedNumber: 0   integral: 1   rc: 0   numZeros: 0
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 1
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 2
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 3
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 4
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 5
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 6
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 7
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 8
L109   detectedNumber: 0   integral: 0   rc: 0   numZeros: 9
L150   detectedNumber: 0   integral: 0   rc: -1   numZeros: 0
Moteino sleep


PS - I just purchased my first Moteino, the MotionMote.  For the past week or so I've been trying different sketches and trying to learn about the Moteino and the RFM69.  This is way too addictive and fun!
Title: Re: ShockTest.ino question
Post by: TomWS on May 06, 2017, 07:36:21 AM
Before we get into your questions and results, do you understand WHAT the sketch is trying to do?

Things to understand:
1. What is the MOTIONPIN connected to?  And what is it measuring?
2. What is the relationship between MOTIONPIN and MOTIONINT?
3. What is the purpose of motionIRQ() function and how does it get called?
4. Do you know what an 'integrator' is?  (I'm not being flip here, just trying to know at what level to answer your question)

Tom
Title: Re: ShockTest.ino question
Post by: JonM on May 06, 2017, 10:17:29 AM
Hi Tom!

I'm 99% sure I've figured out the first three.
1)  The MOTIONPIN connected to the PIR.  No motion = output low = MOTIONPIN low. Opposite levels for motion detected.
2&3)  When the PIR detects motion, the output goes high and the MOTIONPIN goes high. That causes the Moteino to wake up, and causes an interrupt, and runs a small function called motionIRQ via attachInterrupt(MOTIONINT, motionIRQ, RISING). (bad run on!)  motionIRQ basically counts how many PIR pulses are detected within a sample time.
4)  No, I do not know what an integrator is and this is where I am struggling.

No worries about being flip.  Feel free to ask any questions. 

I do know there is a MotionMote sketch and I've downloaded & loaded it up also.  I'm just trying different things to help me learn more.
Title: Re: ShockTest.ino question
Post by: TomWS on May 06, 2017, 10:53:57 AM
Ok, this is good.  Now I know where to focus.

The test program was designed for an accelerometer interrupt (if I recall correctly and given the name of the sketch) to filter out short bursts of shock/vibration, or, in your case, motion detected by the PIR (like leaves blowing by in the wind or your dog chasing a squirrel).  By 'integrating' (summing) the pulses, the logic will trip only when there were a certain number of pulses within a given time, so, in the original case, the logic would trip when there were at least 10 vibrations in 500mS.  If there were 10 within 50mS it would trip.  If there were 9 within 500mS, it wouldn't.  It would only trip if there were at least 10 within any 500mS window.  If an interval of 50mS did not have a pulse, the 'sum' would be decremented by 1, draining off the count until it was 0.  If there were 100, the count would saturate at 10 so that the next 500mS window wasn't 'fooled' by the high pulse count previously.

Now, will this be useful for a PIR?  I'm not sure since it doesn't 'pulse' as I understand it,  I think it stays active as long as there is motion so it is already integrating the motion.  What you MAY want is something that will trip if there is a sustained active level for a certain length of time, but that would be different logic and probably wouldn't require an interrupt or counter...

Tom 
Title: Re: ShockTest.ino question
Post by: JonM on May 06, 2017, 01:28:45 PM
Tom,
That all helps - Thank you!  Now I've got to go try a few things.  I didn't realize the integral could start counting down and then count up and cause the radio to send "HI".  I don't think I am seeing the second increase.  Time to test!

QuoteI'm not sure since it doesn't 'pulse' as I understand it,  I think it stays active as long as there is motion so it is already integrating the motion
For the PIR there are pulses related to movement.  So if I walk away from the PIR (or move my hand away from the PIR) there is a series of pulses that cause "Motion detected, number: n"

So I was looking for a few pulses before firing off a radio message (or the Motion detected, number message).  But I may need to look for a something else (e.g., the "stays active as long as there is motion").


    if (detectedNumber) // did we get any interrupts inside of this window?
    {
      integral += detectedNumber;   // yes accumulate them
      detectedNumber=0;             // reset the counter
      // DEBUG - ok to do here since it's outside of interrupt handler and we've only masked OUR interrupt
      message = s + integral;
      DEBUGln(message);
    }


EDIT: not sure if this is the right way to document a pulse stream.

for PIR each digit is 50ms

50 ms pulse followed by 150ms pulse - fast hand swipe in front of lens
0000000001000111000000000000000....

200ms pulse followed by 600ms pulse - walking directly at PIR
00000000011110001111111111110000000011111111111111111111110000000000000000111100001111111111111111...

550ms pulse followed by 200ms pulse - walking away from PIR
00000000011111111111011110011111111111101111111111111101111111111111111111101111111111111000000000...