/*
MotionSensor - A MySensors Motion Sensor sketch for use with hacked Ikea Molgan.
Created by Ivo Pullens, Emmission, 2016
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#define MY_RADIO_NRF24
#define MY_BAUD_RATE (57600)
#define MY_WITH_LEDS_BLINKING_INVERSE
#define MY_DEFAULT_TX_LED_PIN (A5)
#include
#include
#define PIR_PIN (3)
#define CHILD_ID_PIR (0)
const float VccMin = 1.8; // Minimum expected Vcc level, in Volts: Brownout at 1.8V -> 0%
const float VccMax = 2.0 * 1.6; // Maximum expected Vcc level, in Volts: 2xAAA fresh Alkaline -> 100%
const float VccCorrection = 1.0; // Measured Vcc by multimeter divided by reported Vcc
static Vcc vcc(VccCorrection);
#define SENSOR_SLEEP_TIME_MS (24UL*60UL*60UL*1000UL) // Maximum time between sensor wakeups, e.g. to check battery level.
#define PIR_BLIND_TIME_MS (30UL*1000UL) // Time PIR will not report new triggers after being triggered
void presentation()
{
sendSketchInfo("Molgan", "1.0");
present(CHILD_ID_PIR, S_MOTION);
}
void setup()
{
pinMode(PIR_PIN, INPUT);
}
void loop()
{
// Sleep until woken by interrupt or timer.
bool pirTripped = sleep(digitalPinToInterrupt(PIR_PIN), CHANGE, SENSOR_SLEEP_TIME_MS) >= 0;
// Only send tripped state. Tripped goes low again after a configurable time on the PIR sensor,
// and it doesn't make sense to send this state to the gateway. Better save some battery juice.
// If you still want to send the low level, then remove the if-statement.
if (pirTripped)
{
send( MyMessage(CHILD_ID_PIR, V_TRIPPED).set(uint8_t(pirTripped)) );
}
// Try to determine battery level after sending sensor data, so battery will just have experienced some load.
uint8_t batteryPcnt = static_cast(0.5 + vcc.Read_Perc(VccMin, VccMax));
// Battery readout should only go down. So report only when new value is smaller than previous one.
static uint8_t oldBatteryPcnt = 200;
if ( batteryPcnt < oldBatteryPcnt )
{
sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
}
// Sleep for a short while, ignoring any new triggers.
if (pirTripped)
{
sleep(PIR_BLIND_TIME_MS);
}
}