Dediggefedde

clockHitter

Aug 12th, 2018
29
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <avr/sleep.h>
  2. #include <avr/wdt.h>
  3.  
  4. #ifndef cbi
  5. #define cbi(sfr,bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  6. #endif
  7. #ifndef sbi
  8. #define sbi(sfr,bit) (_SFR_BYTE(sfr) |= _BV(bit))
  9. #endif
  10.  
  11. volatile boolean f_wdt = 1;
  12.  
  13. #define D_MOTOR 11 //PMW to dimm Motor later
  14. #define D_LED 13 //LED to display status
  15. #define D_PUSH 12 //Taster, um die Uhr weiter zu stellen
  16.  
  17. unsigned int timer; //zählt sekunden bis 12*60*16 (0.5d)
  18. unsigned short motorTime; //time in s the motor is hitting the clock
  19. unsigned short pushed;
  20. unsigned short i;
  21. unsigned short interval, intBig;
  22. unsigned short watchDogDelay;
  23.  
  24. void setup() {
  25.   pinMode(D_MOTOR, OUTPUT);
  26.   pinMode(D_LED, OUTPUT);
  27.   pinMode(D_PUSH, INPUT);
  28.  
  29.   timer = 0;
  30.   motorTime = 3;
  31.   pushed = 0;
  32.   interval = 60*60; //interval between motorpulses in s
  33.   intBig = 12; //# of intervalls before double pulse
  34.  
  35.   Serial.begin(9600);
  36.   while (! Serial){};
  37.   cbi(SMCR, SE); //sleep mode enable
  38.   cbi(SMCR, SM0); //power down mode
  39.   cbi(SMCR, SM1); //power down mode
  40.   cbi(SMCR, SM2); //power down mode
  41.   setup_watchdog(6);//1s rest
  42. }
  43.  
  44.  
  45. void loop() {
  46.   if (f_wdt == 1) { //once per watchdog-wakeup
  47.     f_wdt = 0;
  48.  
  49.     i = 0;
  50.     bool canSleep = false; //sleep or delay
  51.     if (digitalRead(D_PUSH) == HIGH) { //push button to set the current hour
  52.       ++pushed;
  53.       if (pushed > 12)pushed = 0; //12h mode
  54.       for (i = 0; i < pushed; ++i) { //blink for each hour that is now set
  55.         digitalWrite(D_LED, HIGH);
  56.         delay(40);
  57.         digitalWrite(D_LED, LOW);
  58.         delay(40);
  59.       }
  60.       if (pushed == 0) { //hour=0 ► one long pulse
  61.         digitalWrite(D_LED, HIGH);
  62.         delay(400);
  63.         i = 5;
  64.         digitalWrite(D_LED, LOW);
  65.       }
  66.       timer = interval * pushed; //set the internal timer to the selected time
  67.       canSleep = false; //don't sleep: use less delay since blinking took time.
  68.     } else {
  69.       if ((((timer % interval) < motorTime) or ((timer > (interval * intBig))))) { //check if it's time for motor
  70.         digitalWrite(D_MOTOR, HIGH);
  71.         canSleep = false; //don't sleep while motor is running!
  72.         Serial.println("x"); //logging / calibrating
  73.       } else {
  74.         digitalWrite(D_MOTOR, LOW);
  75.         canSleep = true; //sleep when idle
  76.       }
  77.  
  78.       if (( timer > (interval * intBig) + 2 * motorTime)) //after 12h reset the timer
  79.         timer -= interval * intBig;
  80.     }
  81.  
  82.     if (canSleep) { //sleepmode when idle
  83.       pinMode(D_MOTOR, INPUT); //input mode takes less power
  84.       pinMode(D_LED, INPUT);
  85.       system_sleep();
  86.       pinMode(D_MOTOR, OUTPUT); //restore pinmodes
  87.       pinMode(D_LED, OUTPUT);
  88.       timer += 1; //1s passed.
  89.       //if (++watchDogDelay>10){++timer;watchDogDelay-=10;} //Calibration for watchdog timer: all 10s 1s delay
  90.       } else {
  91.       delay(1000 - i * 80); //1s delay - time of blinks
  92.       ++timer;//1s passed.
  93.     }
  94.   }
  95. }
  96. void system_sleep() {
  97.   cbi(ADCSRA, ADEN); //ADC off
  98.   set_sleep_mode(SLEEP_MODE_PWR_DOWN); //sleep mode set
  99.   sleep_enable();
  100.   sleep_mode(); //system sleeps till watchdog wakes up
  101.   sleep_disable();//wake up system
  102.   sbi(ADCSRA, ADEN); //ADC on
  103. }
  104.  
  105. //0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1s, 7=2s, 8=4s, 9=8s
  106. void setup_watchdog(int ii) {
  107.   byte bb;
  108.   //int ww;
  109.   if (ii > 9)ii = 9;
  110.   bb = ii & 7;
  111.   if (i > 7)bb |= (1 << 5);
  112.   bb |= (1 << WDCE);
  113.   //ww=bb;
  114.  
  115.   MCUSR &= ~(1 << WDRF);
  116.   //start time sequence
  117.   WDTCSR |= (1 << WDCE) | (1 << WDE);
  118.   //set new watchdog time value
  119.   WDTCSR = bb;
  120.   WDTCSR |= _BV(WDIE);
  121. }
  122.  
  123. ISR(WDT_vect) { //watchdog wakes up
  124.   f_wdt = 1;
  125. }
RAW Paste Data