Hi. I'm trying to awaken an Arduino to turn on 2 LEDs via a rising interrupt call from a PIR sensor. The LEDs stay on for 15000 ms after the PIR sensor is activated for the last time. This means reactivations of the sensor before the LEDs go off, should restart the timer. This is where the problem is - restarting the timer upon reactivation.
My last attempt was to add the val1 variable to the code and instead of counting to 15000ms, it is now stuck int the for loop and the timer resets after about 5 ms each time and doesn't reach the 50000 ms break, but I am posting the code like this because at least those 2 lines are being called. Not sure if this was the closest I got to being correct. Note: the interrupt is near the end but I thought the full code would be relevant to post because it has all the sleep code.
// PIR motion detector sensor with Arduino nano in ultimate power saving mode
//(reducing power consumption almost by 70% (4.7mA) of normal operation consumption (13mA))
// Current code by Electromania 24th Feb 2016 //https://youtu.be/n-Oiz76aVYs
// Thanks to:- http://playground.arduino.cc/Learning/ArduinoSleepCode for information about sleep.h library and modes
// http://www.kevindarrah.com/download/arduino_code/LowPowerVideo.ino
// for useful explanation of "Low Power Arduino! Deep Sleep Tutorial" for bare arduino uno chip
// http://www.atmel.com/images/atmel-8271-8-bit-avr-microcontroller-atmega48a-48pa-88a-88pa-168a-168pa-328-328p_datasheet_complete.pdf // datasheet
#include <avr/interrupt.h> // Library to use interrupt
#include <avr/sleep.h> // Library for putting our arduino into sleep modes
const int PIRsensorInterrupt = 0; //interrupt 0 at arduino nano pin D2
const int LedPin1 = 11; // external LED or relay connected to pin 11
const int LedPin2 = 12; // external LED or relay connected to pin 12
volatile int PIRsensorstate = HIGH; // current state of the button
volatile int LastPIRsensorstate = 0;
volatile int x = 0;
volatile int val1 = 0;
void wakeUpNow(){ // Interrupt service routine or ISR
PIRsensorstate == HIGH;
}
void setup() {
pinMode(LedPin1, OUTPUT); // initialize pin 11 as an output pin for LED or relay etc.
pinMode(LedPin2, OUTPUT); // initialize pin 12 as an output pin for LED or relay etc.
Serial.begin(115200); // initialize serial communication only for debugging purpose
Serial.println("Warming up... wait for a min...");
// delay execution of sketch for a min, to allow PIR sensor get stabilized
for( int i = 1; i <= 200; i++){ // LED at pin 13 blinks until PIR sensor is stabilized
digitalWrite(LedPin1, HIGH);
delay(5);
digitalWrite(LedPin1, LOW);
delay(5);
digitalWrite(LedPin2, HIGH);
delay(5);
digitalWrite(LedPin2, LOW);
delay(5);
}
Serial.println("Ready");
pinMode(PIRsensorInterrupt, INPUT); // define interrupt pin D2 as input to read interrupt received by PIR sensor
}
void Hibernate() // here arduino is put to sleep/hibernation
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // lowest power consumption mode
//"The Power-down mode saves the register contents but freezes the Oscillator, disabling all other chip functions
// until the next interrupt or hardware reset." text from ATMEGA328P datasheet
ADCSRA &= ~(1 << 7); // Disable ADC - don't forget to flip back after waking up if you need ADC in your application ADCSRA |= (1 << 7); (From Kevin's sketch)
sleep_enable(); // enable the sleep mode function
sleep_bod_disable(); //to disable the Brown Out Detector (BOD) before going to sleep.
attachInterrupt(digitalPinToInterrupt(PIRsensorInterrupt),wakeUpNow, RISING); // Attach interrupt at pin D2 (int 0 is at pin D2 for nano, UNO)
// here since PIR sensor has inbuilt timer to swtich its state from OFF to ON, we are detecting its CHANGE IN STATE to control our LED/relay at pin 13.
// therefore, we will not need to use arduino delay timer to Set "ON time" of our LED/relay, it can be adjusted physically using potentiometer provided on PIR sensor board.
// This further helps in using SLEEP_MODE_PWR_DOWN which is ultimate lowest power consumption mode for ATMEGA8328P chip
//(please note - because of onboard power regulators of arduino boards, power consumption cannot be reduced to predicted few microAmps level of bare chips.
//To achieve further reduction in current consumption, we will need bare ATMEGA328P chip)
for (int i = 0; i < 20; i++) {
if(i != 11)// because the LED/Relay is connected to digital pin 11
if(i != 12)// because the LED/Relay is connected to digital pin 12
pinMode(i, INPUT);
}
sleep_mode(); // calls function to put arduino in sleep mode
sleep_disable(); // when interrupt is received, sleep mode is disabled and program execution resumes from here
detachInterrupt(PIRsensorInterrupt); // we detach interrupt from pin D2, to avoid further interrupts until our ISR is finished
}
void loop() {
interrupts(); // enable interrupts for Due and Nano V3
if ((PIRsensorstate == HIGH) && (LastPIRsensorstate == 0)); {
Serial.println("rise detected - PIR HIGH");
digitalWrite(LedPin1, HIGH); digitalWrite(LedPin2, HIGH);
for (x = 0; x < 12000; x ++) {Serial.println(x); val1 = digitalRead(PIRsensorstate);
if ((val1 == LOW) && (LastPIRsensorstate == 1)) {
LastPIRsensorstate = 0; Serial.println("PIR LOW");
}
if ((val1 == HIGH) && (LastPIRsensorstate == 0)) {
LastPIRsensorstate = 1; x = 0; Serial.println("PIR REACTIVATED");
}
if (x == 12000) {
break;
}
}
}
Serial.println(x); Serial.println("hibernating");
Serial.print("PIRsensorstate = "); Serial.print(PIRsensorstate); Serial.print(" ");
Serial.print("LastPIRsensorstate = "); Serial.println(LastPIRsensorstate);
digitalWrite(LedPin1, LOW); digitalWrite(LedPin2, LOW); x = 0;
Hibernate();
}