I have a project where I'm using an ATTiny44 (similar to ATTiny85 but with more IO) to create a nightlight that will turn on at dusk, stay on for 4 hours and then after 4 hours go into sleep mode for 18 hours. I will do this by increment a count every 8 seconds it wakes briefly until that limit is reached (8100). Once it is dusk again it will repeat the process. I also want to be able to take it out of sleep mode at any time using interrupt pin 8 (PCINT5).
I've pieced together the code below from various contributors and will integrate this eventually into my sketch for the nightlight. What I'm having trouble with below is pulling it out of sleep mode. When I initiate the interrupt, it should pull it out of sleep indefinitely when daylight, but for some reason it does not because I can observe that my pinLED DOES NOT flash at 1 second intervals but stays lit constantly with a brief 20ms flash?
What I'm I missing? Do I need to disable (GIMSK) my interrupt pin when not sleeping?
thanks in advance
Mark
/*
Pin Change Interrupt Example
Version: 1.0
Author: Alex from Inside Gadgets (http://www.insidegadgets.com)
Created: 25/02/2011
* *adopted by Mark Biasotti 07/27/19 with watchdog timer which lets sleep for 8 seconds
Demonstration of the pin change interrupt
LED on digital pin 7
Interrupt on digital pin 8
10k resistor on digital pin 8 to GND
*/
#include <avr/sleep.h>
#include <avr/wdt.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int pinLed = 7;
int greenled = A0; // green led - port pin A0 attach to leg 13 of attiny44
int redled = A1; // red led - port pin A1 attach to leg 12 of attiny44
int pininterrupt = 8;
int flag_interrupt = 0;
int sensorpin = A3;
int sensorValue;
void setup() {
pinMode(pinLed, OUTPUT);
pinMode(pininterrupt, INPUT);
pinMode(sensorpin,INPUT);
pinMode(greenled, OUTPUT);
pinMode(redled, OUTPUT);
digitalWrite(redled, HIGH); // set to off initially
digitalWrite(greenled, HIGH); // set to off initially
sbi(GIMSK, PCIE0); // Turn on Pin Change interrupt
sbi(PCMSK0, PCINT5); // physical pin 8 on attiny44 - Which pins are affected by the interrupt
wdt_enable(WDTO_8S); // watchdog timer with 8 seconds time out
}
void Flash_LED() {
for (int i = 0; i < 4; i++) {
digitalWrite(greenled, LOW); // MODE 1 = indicator that cpu has woke up
digitalWrite(redled, LOW);
delay(500);
digitalWrite(greenled, HIGH);
digitalWrite(redled, HIGH);
delay(500);
}
}
void loop() {
sensorValue = (analogRead(sensorpin) / 4); // poll ambient light condition
digitalWrite(pinLed, HIGH); //this LED blinks when not in sleep
delay(1000);
digitalWrite(pinLed, LOW);
if (flag_interrupt == 1) { // if interrupt switch is press cpu is woke up
sleep_disable();
sbi (ADCSRA, ADEN); // Switch Analog to Digital converter ON
Flash_LED();
}
else if (sensorValue < 100) // if dark cpu sleeps
{
flag_interrupt == 0;
wdt_reset();
system_sleep();
}
}
// From http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void system_sleep() {
cbi(ADCSRA, ADEN); // Switch Analog to Digital converter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
sleep_mode(); // System sleeps here
sbi(ADCSRA, ADEN); // Switch Analog to Digital converter ON
}
ISR(PCINT0_vect) {
flag_interrupt = 1;
}