// Attiny85 sleep, interrupt with servo
// https://forum.arduino.cc/t/attiny85-sleep-interrupt-with-servo/1399429
#include <avr/sleep.h>
#define servoPin PB0
#define LED PB1
#define piezoSensor PB2
#define LED2 PB3
#define LED_ON_DURATION 500
#define BLINK_RATE 200
volatile uint32_t switchLedOffNow = 0;
// Interrupt Service Routine for PCINT0
ISR(PCINT0_vect) {
EIMSK &= ~bit(PCIE); // Turn off pin change interrupts
sleep_disable();
// pinMode(servoPin, OUTPUT);
// pinMode(LED, OUTPUT);
// pinMode(LED2, OUTPUT);
DDRB |= bit(servoPin) | bit(LED) | bit(LED2); // Do it in one go
digitalWrite(LED, HIGH);
switchLedOffNow = millis() + LED_ON_DURATION;
}
void sleep() {
// Disable all OUTPUTs to save even more energy
pinMode(servoPin, INPUT);
pinMode(LED, INPUT);
pinMode(LED2, INPUT);
// DDRB &= ~(bit(servoPin) | bit(LED) | bit(LED2)); // Do it in one go
sleep_enable();
noInterrupts();
// Turn on pin change interrupts
EIMSK |= bit(PCIE);
PCMSK1 |= bit(piezoSensor) ;
// Enable global interrupts
interrupts();
sleep_cpu();
}
void setup() {
// pinMode(servoPin, OUTPUT);
// digitalWrite(LED, LOW);
// pinMode(LED, OUTPUT);
// Disable ADC - saves about 324.5uA in sleep mode!
// ADCSRA &= ~bit(ADEN); // Disable ADC
ADCSRA = 0; // Disable ADC
ACSR |= bit(ACD); // Disable analog comparator
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep();
}
void blinkIfAlive() {
static uint32_t nextBlink = 0;
if (millis() > nextBlink) {
digitalWrite(LED2, !digitalRead(LED2));
nextBlink += BLINK_RATE; // #define BLINK_RATE 200 or whatever
}
}
// uint32_t i = 0;
void loop() {
// static uint32_t nextSecond = millis() + 1000;
// i++;
// if (millis() > nextSecond) {
// Debug.print(i);
// Debug.println(F(" loops/s"));
// nextSecond += 1000;
// i = 0;
// }
if (digitalRead(LED)) {
// Do whatever has to be done
if (millis() > switchLedOffNow) {
digitalWrite(LED, LOW);
sleep();
}
}
blinkIfAlive();
}