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!
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
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.
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
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...