Looking for the right solution

Dear Forum,

I am not a programmer from profession, so i might sounf a bit simple.
Trying to get a graphic with the device code below.
Want to register de number of times the PIR is triggered every 10 minutes and then register the counter, light level and power.
My problem is the PIR trigger which is not counting the events.

Can anyone help with this (simpe??) problem?

Thanks for reply in advance.

Arjen

Device code:
/********************************************************************************* PIR motion sensor device code written in Squirrel For more information on connecting a PIR sensor, check out the following two links: http://electricimp.com/docs/api/hardware/pin/read/ http://codergirljp.blogspot.com/2014/01/electric-imp-hello-world-motion-sensor.html *********************************************************************************/ // Assign pin1 to your PIR sensor. This is important because pin1 supports // wake-from-sleep (which allows you to avoid looping). pir_sensor <- hardware.pin1; local pir_state = pir_sensor.read(); local pir_count = 0 //motionDetected` will be called each time the PIR sensor’s state
// changes (so, for both “on” and “off” states). We’re going to do all
// our LED state and logging work in here.
function motionDetected() {
local pir_state = pir_sensor.read();
local pir_count = pir_count + 1
}

function SendToXively()
{
local light = hardware.lightlevel();
local power = hardware.voltage()
local pir_state = pir_sensor.read();

agent.send("SendToXively", {id = "Impee_LightLevel", value = light});
agent.send("SendToXively", {id = "Impee_PowerLevel", value = power});
agent.send("SendToXively", {id = "Impee_MotionSensor", value = pir_count});

local pir_count = 0    
imp.sleep(600);   // 10 minutes

}
SendToXively();`

If you want to wake the imp on pin1 being high (note: not on low, not on transition, just on high level), then you need to put it to sleep expecting a wake on pin1. You have not configured your pin1 as an input, so you need to set pir_sensor.configure(DIGITAL_IN_WAKEUP, motionDetected);

That will at least start calling your pir counting function when the pin goes high. But then you need to check in motionDetected whether it was pin1 that woke you up from sleep, with something like
// did pin 1 just wake us up? if (hardware.wakereason()==WAKEREASON_PIN1) { agent.send("button", "Motion detected"); }

And you would also need to monitor when the pulse transitions to high and to low again so that you only count 1 for each pulse, all getting quite complicated.

I would say that you need a different approach, probably configure your input as a counter so that it can independently count input pulses using pin.configure(PULSE_COUNTER, float, integer) as in the documentation. Let the hardware do the counting for you.

Perhaps I should add that pin1 as DIGITAL_IN_WAKEUP wakes the imp from deep sleep, not from normal sleep. So the design model is that you send the imp into deep sleep, and pin1 wakes it up to start code execution from the beginning. This is why you need to test for the wake reason to see if you have been woken by pin1 or by a power reboot or several other reasons.

Another consideration is that in deep sleep all variables are lost, so you would have to store your current count in nvram which is preserved during deep sleep. Here is an example of logging to nvram then reporting it to the agent every hour:

`// Log an ADC value each minute, only tell the server once an hour

t <- time();

function hourly() {
agent.send(“hourlydata”, nv.data);
nv.data = “”;
server.expectonlinein(3600);
}

function log() {
local min = (t/60) % 60;
hardware.pin9.configure(ANALOG_IN)
// nv.data = nv.data + format(" %d", hardware.pin9.read());
nv.data = nv.data + format(" %0.3f", hardware.voltage());
if (min == 00) {
hourly();
}
imp.onidle(function() { imp.deepsleepfor(60 - (time() % 60)); });
}

if (!(“nv” in getroottable())) {
nv <- { data = “” };
server.log(“clearing nv memory”);
}

imp.onidle(log);`

Finally, deep sleep is only useful to cut power consumption for battery powered devices that need to run for weeks or months with occasional wakeups due to activity to be logged.

Since you do not appear to be deep sleeping or careful about battery, I think your better options are

  • to use the COUNTER mode so the hardware does the counting, or
  • to set pin1 as a normal DIGITAL_IN with a callback function that is called whenever the pin state changes, such as:

`
pir_sensor <- hardware.pin1;
led <- hardware.pin9;
led.configure(DIGITAL_OUT);
led.write(1)
local pir_count = 0;

// motionDetected will be called each time the PIR sensor’s state
// changes (so, for both “on” and “off” states). We’re going to do all
// our LED state and logging work in here.
//
function motionDetected() {
led.write(pir_sensor.read())
if (pir_sensor.read() == 1) {
pir_count = pir_count + 1;
}
// if state is zero, do not increment pir_count
}
pir_sensor.configure(DIGITAL_IN_PULLUP, motionDetected);

function SendToXively()
{
local light = hardware.lightlevel();
local power = hardware.voltage()

agent.send("SendToXively", {id = "Impee_LightLevel", value = light});
agent.send("SendToXively", {id = "Impee_PowerLevel", value = power});
agent.send("SendToXively", {id = "Impee_MotionSensor", value = pir_count});

pir_count = 0    // reset the count after reporting it
imp.wakeup(600, SendToXively);  // then trigger another report in 10 minutes

}

SendToXively();
`

The main structural point here is that the last line of SendToXively sets up a timer to trigger it again in 10 minutes. This could also be the first line of the function, the important thing is that this is the imp way to set up a repeated timed event. In the background the pir sensor is being counted by motionDetected, and this count is reported and reset every 10 minutes by SendToXively. I think this is what you wanted to achieve, and it does not involve using the ability of pin1 to wake the imp (from deep sleep).

Thank You!! DrJack.

This exact what i was looking for.
Helped and learned a lot!!

Sorry about all the lecturing on the way :wink: You were getting close, and perhaps my talk about pin1 wakeup was a red herring following this comment in your code:

// Assign pin1 to your PIR sensor. This is important because pin1 supports // wake-from-sleep (which allows you to avoid looping).

It is not necessary to use pin1 when using a callback function like motionDetected, any pin can do that, without “looping”. Pin1 has the unique property of being able to wake the imp from deep sleep in very low power applications, and it will normally be used in conjunction with DIGITAL_IN_WAKEUP, deepsleepfor() or deepsleepuntil(), and hardware.wakereason().

Good luck with further development!