Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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
- volatile boolean f_wdt = 1;
- #define D_MOTOR 11 //PMW to dimm Motor later
- #define D_LED 13 //LED to display status
- #define D_PUSH 12 //Taster, um die Uhr weiter zu stellen
- unsigned int timer; //zählt sekunden bis 12*60*16 (0.5d)
- unsigned short motorTime; //time in s the motor is hitting the clock
- unsigned short pushed;
- unsigned short i;
- unsigned short interval, intBig;
- unsigned short watchDogDelay;
- void setup() {
- pinMode(D_MOTOR, OUTPUT);
- pinMode(D_LED, OUTPUT);
- pinMode(D_PUSH, INPUT);
- timer = 0;
- motorTime = 3;
- pushed = 0;
- interval = 60*60; //interval between motorpulses in s
- intBig = 12; //# of intervalls before double pulse
- Serial.begin(9600);
- while (! Serial){};
- cbi(SMCR, SE); //sleep mode enable
- cbi(SMCR, SM0); //power down mode
- cbi(SMCR, SM1); //power down mode
- cbi(SMCR, SM2); //power down mode
- setup_watchdog(6);//1s rest
- }
- void loop() {
- if (f_wdt == 1) { //once per watchdog-wakeup
- f_wdt = 0;
- i = 0;
- bool canSleep = false; //sleep or delay
- if (digitalRead(D_PUSH) == HIGH) { //push button to set the current hour
- ++pushed;
- if (pushed > 12)pushed = 0; //12h mode
- for (i = 0; i < pushed; ++i) { //blink for each hour that is now set
- digitalWrite(D_LED, HIGH);
- delay(40);
- digitalWrite(D_LED, LOW);
- delay(40);
- }
- if (pushed == 0) { //hour=0 ► one long pulse
- digitalWrite(D_LED, HIGH);
- delay(400);
- i = 5;
- digitalWrite(D_LED, LOW);
- }
- timer = interval * pushed; //set the internal timer to the selected time
- canSleep = false; //don't sleep: use less delay since blinking took time.
- } else {
- if ((((timer % interval) < motorTime) or ((timer > (interval * intBig))))) { //check if it's time for motor
- digitalWrite(D_MOTOR, HIGH);
- canSleep = false; //don't sleep while motor is running!
- Serial.println("x"); //logging / calibrating
- } else {
- digitalWrite(D_MOTOR, LOW);
- canSleep = true; //sleep when idle
- }
- if (( timer > (interval * intBig) + 2 * motorTime)) //after 12h reset the timer
- timer -= interval * intBig;
- }
- if (canSleep) { //sleepmode when idle
- pinMode(D_MOTOR, INPUT); //input mode takes less power
- pinMode(D_LED, INPUT);
- system_sleep();
- pinMode(D_MOTOR, OUTPUT); //restore pinmodes
- pinMode(D_LED, OUTPUT);
- timer += 1; //1s passed.
- //if (++watchDogDelay>10){++timer;watchDogDelay-=10;} //Calibration for watchdog timer: all 10s 1s delay
- } else {
- delay(1000 - i * 80); //1s delay - time of blinks
- ++timer;//1s passed.
- }
- }
- }
- void system_sleep() {
- cbi(ADCSRA, ADEN); //ADC off
- set_sleep_mode(SLEEP_MODE_PWR_DOWN); //sleep mode set
- sleep_enable();
- sleep_mode(); //system sleeps till watchdog wakes up
- sleep_disable();//wake up system
- sbi(ADCSRA, ADEN); //ADC on
- }
- //0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1s, 7=2s, 8=4s, 9=8s
- void setup_watchdog(int ii) {
- byte bb;
- //int ww;
- if (ii > 9)ii = 9;
- bb = ii & 7;
- if (i > 7)bb |= (1 << 5);
- bb |= (1 << WDCE);
- //ww=bb;
- MCUSR &= ~(1 << WDRF);
- //start time sequence
- WDTCSR |= (1 << WDCE) | (1 << WDE);
- //set new watchdog time value
- WDTCSR = bb;
- WDTCSR |= _BV(WDIE);
- }
- ISR(WDT_vect) { //watchdog wakes up
- f_wdt = 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement