blogging after 5 years
As long as I could remember I wanted to make a motion activated switch which can run on batteries for days/months.
2016 I gave it first short . with Arduino pro mini , 18650 3.7V battery , PIR sensor , LDR , servo and dual H bridge driver . After full charge ~4.2V the circuit worked as expected i.e switching ON when it detects motion and turn OFF when there is no motion detected for ~1min .
then once the battery drained to a point around ~3.7V , Arduino started getting reset when ever the servo motor moves . battery didn't have enough power to drive servo and maintain stable voltage . Note I didn't have voltage regulator to save power .
here is the video
After the above v1.0 his I have made below changes for v2.0
instead of one bulky 18650 battery switched to 4 AAA 800mAh
swapped dual H bridge driver with a single N-channel enhancement MOSFET
v2.0 idle/standby current is 350micro Amps , batteries should easily last for 1-2months
fritzing schematic
//Arduino code for v2.0 goes something like this . will post video and schematic at later time
#include <LowPower.h>
static const uint8_t LDRPin = A7 ;
static const uint8_t LDRPin_source = 7 ;
static const uint8_t pirPin = 2;
static const uint8_t mosfet_pin = 5;
static const uint8_t servoPin = 8;
uint8_t cnt = 0;
bool is_light_on = false;
byte val;
void ServoOn () {
digitalWrite(mosfet_pin, HIGH);
LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
}
void ServoOff() {
digitalWrite(mosfet_pin, LOW);
LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
}
void ServoInitialize() {
pinMode(servoPin, OUTPUT);
}
void PirInitialize() {
pinMode(pirPin, INPUT);
}
void LdrInitialize() {
pinMode(LDRPin_source, OUTPUT);
digitalWrite(LDRPin_source, LOW);
}
void MotorModuleInitialize () {
pinMode(mosfet_pin, OUTPUT);
}
void setup() {
LdrInitialize();
PirInitialize();
ServoInitialize();
MotorModuleInitialize ();
readAnalogValue();
delay(30);
pinMode(LED_BUILTIN, OUTPUT);
for (cnt = 0 ; cnt < 3 ; cnt++ ) {
if ( cnt % 2 == 0 ) {
digitalWrite(LED_BUILTIN, LOW);
} else {
digitalWrite(LED_BUILTIN, HIGH);
}
delay(1000);
}
switch_on();
}
int LdrReading = 0;
void readAnalogValue () {
digitalWrite(LDRPin_source, HIGH);
delayMicroseconds(50);
LdrReading = analogRead(LDRPin);
delayMicroseconds(5);
digitalWrite(LDRPin_source, LOW);
}
unsigned long my_time;
void set_angle(int val, int cnt) {
for ( int i = 0 ; i < cnt ; i++ ) {
digitalWrite(servoPin, HIGH);
delayMicroseconds(val);
digitalWrite(servoPin, LOW);
LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);
}
}
void switch_mid() {
ServoOn ();
set_angle(100 * 16, 2 * 16 );
ServoOff();
}
void switch_on() {
is_light_on = true ;
ServoOn ();
set_angle(93 * 16, 2 * 16 );
ServoOff();
}
void switch_off() {
is_light_on = false ;
ServoOn ();
set_angle(40 * 16, 2 * 16 + 2 );
ServoOff();
}
void motionDetection()
{
val = digitalRead(pirPin);
if (val == HIGH && is_light_on == false) {
readAnalogValue();
if ( LdrReading > 985 ) {
switch_on();
}
} else if ( val == LOW && is_light_on == true ) {
switch_off();
}
}
void wakeUp () { }
void loop () {
attachInterrupt(digitalPinToInterrupt(pirPin), wakeUp, CHANGE);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
detachInterrupt(digitalPinToInterrupt(pirPin));
motionDetection();delay(100);
}