#include #include #include #include // Utility macros #define adc_disable() (ADCSRA &= ~_BV(ADEN)) // disable ADC (before power-off) #define adc_enable() (ADCSRA |= _BV(ADEN)) // re-enable ADC #define enable_pin_interrupts() (GIMSK |= _BV(PCIE)) // Enable Pin Change Interrupts // Pins #define SWITCH 0 #define SENDER 2 #define CONTROLLER 4 RCSwitch mySwitch = RCSwitch(); char* WND_OPEN = "00000000000000000000000001000001"; char* WND_CLOSED = "00000000000000000000000001100001"; int counter = 0; bool currentState; void setup() { pinMode(SWITCH, INPUT_PULLUP); pinMode(CONTROLLER, OUTPUT); digitalWrite(CONTROLLER, LOW); mySwitch.enableTransmit(SENDER); mySwitch.setProtocol(2); updateState(); sendWindowState(); set_sleep_mode(SLEEP_MODE_PWR_DOWN); enable_pin_interrupts(); enableWdt(); } void loop() { sleep(); } void updateState() { currentState = digitalRead(SWITCH); } void sendWindowState() { byte state = digitalRead(SWITCH); if (state == HIGH) { mySwitch.send(WND_OPEN); } else { mySwitch.send(WND_CLOSED); } } void sleep() { PCMSK |= _BV(PCINT0); // Use PB0 as interrupt pin adc_disable(); sleep_enable(); // Sets the Sleep Enable bit in the MCUCR Register (SE BIT) sei(); // Enable interrupts sleep_cpu(); // sleep cli(); // Disable interrupts PCMSK &= ~_BV(PCINT0); // Turn off PB0 as interrupt pin sleep_disable(); // Clear SE bit adc_enable(); sei(); // Enable interrupts } ISR(PCINT0_vect) { sendWindowState(); } ISR(WDT_vect) { bool state = digitalRead(SWITCH); if (state != currentState) { sendWindowState(); updateState(); return; } counter++; if (counter % 76 == 0) { sendWindowState(); counter = 0; } } //enable the wdt for 8sec interrupt void enableWdt() { MCUSR = 0x00; WDTCR |= _BV(WDCE) | _BV(WDE); WDTCR = _BV(WDIE) | _BV(WDP3) | _BV(WDP0); //8192ms }