Converted to timer based delay.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Sat, 2 Jan 2016 01:28:53 +0000 (01:28 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Sat, 2 Jan 2016 01:28:53 +0000 (01:28 +0000)
Use timer0 to count seconds. Checked with oscilloscope to ensure reasonable
accuracy.

fan_control.c

index 0a9d301ae38fed3db02a9bba66ed62e1c82e863d..9398bcef47df610f99321a715859cc20bf35bfae 100644 (file)
@@ -3,7 +3,6 @@
  * ATtiny85 with LED on pin PB2 and a 2N7000 MOSFET on PB3 which controls
  * a computer fan run off 12V supply. Toggle the fan every 15 minutes.
  * Start with the fan ON
- *
  */
 
 #include <avr/io.h>
 #define LED_PIN PB2
 #define FAN_PIN PB3
 
+volatile unsigned long ticks;
+volatile unsigned long seconds;
+volatile unsigned long minutes;
+
+ISR(TIMER0_COMPA_vect)
+{
+    /* count up to 1s (254 ticks) then toggle the LED.
+     * after 15 minutes, toggle the fan
+     * Note: 125Hz on oscillocope is for full wave so on and off.
+     */
+    if (++ticks == 254)
+    {
+        PORTB ^= _BV(LED_PIN);
+        if (++seconds == 61)
+        {
+            if (++minutes == 16)
+            {
+                PORTB ^= _BV(FAN_PIN);
+                minutes = 0;
+            }
+            seconds = 0;
+        }
+        ticks = 0;
+    }
+}
+
+/* put the processor into the currently defined sleep mode */
+inline void sleep_now(void)
+{
+    cli();
+    sleep_enable();
+    sei();
+    sleep_cpu();
+    sleep_disable();
+}
+
+static void
+init_timer0(void)
+{
+    /* Configure timer0 to count at 125 Hz (8ms) */
+    cli();
+    ticks = seconds = minutes = 0;
+    TCCR0A = (1 << WGM01); /* CTC mode */
+    TCCR0B = (1 << CS02); /* prescale PCK/256 */
+    TCNT0 = 0;
+    OCR0A = 125;
+    TIMSK |= (1 << OCIE0A); /* enable timer0 overflow interrupt */
+    sei();   
+}
+
 int
 main(void)
 {
-    unsigned long seconds = 0;
-    uint8_t counter = 0;
-
     wdt_enable(WDTO_1S);
 
     power_adc_disable();
+    power_usi_disable();
 
     /* set all unused pins high-z, led and fan pins output and low */
-    DDRB = _BV(DDB2) | _BV(DDB3);
-    PORTB = ~(_BV(PB2));
+    DDRB = _BV(LED_PIN) | _BV(FAN_PIN);
+    PORTB = ~(_BV(LED_PIN));
 
-    while (1)
+    init_timer0();
+
+    set_sleep_mode(SLEEP_MODE_IDLE);
+    sei();
+
+    for (;;)
     {
-        _delay_ms(250);
+        /* sleep all the time. Gets woken up by the timer at 250Hz */
         wdt_reset();
-        PORTB ^= _BV(PB2); /* toggle led */
-        if (++counter == 4)
-        {
-            if (++seconds == (60 * 15)) /* every 15 mins */
-            {
-                PORTB ^= _BV(PB3); /* toggle fan */
-                seconds = 0;
-            }
-            counter = 0;
-        }
+        sleep_now();
     }
 }