#include <avr/sleep.h>
#define MOTION_PIN 2
#define LDR_PIN 5
#define AWAKE_SECS_AFTER_MOTION 10
/* -------------------------------------------------------------------
* ADC wieder aktivieren.
* https://www.gammon.com.au/adc
*/
void restore_ADC(void) {
ADCSRA=bit(ADEN); // turn ADC on
ADCSRA|=bit(ADPS0)|bit(ADPS1)|bit(ADPS2); // Prescaler of 128
}
/* -------------------------------------------------------------------
* Wird bei LOW-HIGH-Flanke an Pin2 aufgerufen.
* Quelle: http://www.gammon.com.au/power ( Sketch J)
*/
void wake() {
sleep_disable();
detachInterrupt(0);
restore_ADC();
Serial.println("aufgewacht"); delay(10);
}
/* -------------------------------------------------------------------
* CPU in den Tiefschlaf-Modus versetzen.
* Aufwachen durch LOW-HIGH-Flanke an Pin2 bzw. Int0.
*/
void deep_sleep(void) {
Serial.println("Tiefschlaf"); delay(10);
ADCSRA=0; // disable ADC
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
// Do not interrupt before we go to sleep, or the
// ISR will detach interrupts and we won't wake.
noInterrupts();
// will be called when pin D2 goes high
attachInterrupt(0, wake, RISING);
EIFR=bit(INTF0); // clear flag for interrupt 0
// turn off brown-out enable in software
// BODS must be set to one and BODSE must be set to zero within four clock cycles
MCUCR=bit(BODS)|bit(BODSE);
// The BODS bit is automatically cleared after three clock cycles
MCUCR=bit(BODS);
// We are guaranteed that the sleep_cpu call will be done
// as the processor executes the next instruction after
// interrupts are turned on.
interrupts(); // one cycle
sleep_cpu(); // one cycle
}
/* -------------------------------------------------------------------
* Initialisierung nach PowerOn.
*/
void setup() {
Serial.begin(115200);
pinMode(MOTION_PIN, INPUT);
}
/* -------------------------------------------------------------------
* Mainloop.
*/
void loop() {
static int secs_after_motion=0;
Serial.print("(");
Serial.print(secs_after_motion);
Serial.print(", ");
Serial.print(digitalRead(MOTION_PIN));
Serial.print(", ");
Serial.print(analogRead(LDR_PIN));
Serial.print("), ");
if(digitalRead(MOTION_PIN)==LOW) {
if(secs_after_motion>=AWAKE_SECS_AFTER_MOTION) {
secs_after_motion=0;
deep_sleep();
Serial.println("nach deep_sleep()"); delay(10);
}
} else {
secs_after_motion=0;
}
secs_after_motion++;
delay(1000);
}
(0, 0, 543), (1, 0, 545), (2, 0, 549), (3, 0, 559), (4, 0, 571), (5, 0, 577), (6, 0, 579), (7, 0, 580), (8, 0, 578), (9, 0, 575), (10, 0, 570), Tiefschlaf
aufgewacht nach deep_sleep() (1, 1, 539), (1, 1, 545), (1, 1, 543), (1, 1, 213), (1, 1, 187), (1, 0, 191), (2, 0, 188), (3, 0, 191), (4, 0, 195), (5, 0, 202), (6, 0, 199), (7, 0, 520), (8, 0, 536), (9, 0, 547), (10, 0, 555), Tiefschlaf aufgewacht nach deep_sleep() (1, 1, 562), (1, 1, 550), (1, 1, 542), (1, 1, 546), (1, 0, 557), (2, 0, 554), (3, 0, 550), (4, 0, 543), (5, 0, 537), (6, 0, 537), (7, 0, 539), (8, 0, 543), (9, 0, 550), (10, 0, 560), Tiefschlaf |
LDR-Wert | PWM-Wert für die LEDs |
>400 - Tageslicht | 0 - LEDs aus |
100 - 400 - Zwielicht | 255 - LEDs maximal hell |
2 - 99 - Schummerlicht | 50 - LEDs halbwegs hell |
<2 - Dunkelheit | 5 - LEDs ziemlich dunkel |