{"id":84,"date":"2013-08-03T21:03:15","date_gmt":"2013-08-03T10:03:15","guid":{"rendered":"http:\/\/tstarling.com\/blog\/?p=84"},"modified":"2025-06-12T16:14:42","modified_gmt":"2025-06-12T06:14:42","slug":"season-clock","status":"publish","type":"post","link":"https:\/\/tstarling.com\/blog\/2013\/08\/season-clock\/","title":{"rendered":"Season clock"},"content":{"rendered":"<p>My wife Angela wanted a clock for her birthday where its one and only hand would go around once per year.<\/p>\n<p>Sure, I can do that, I said. Angela chose a wall clock to modify, and chose artwork for the dial. I designed and built the circuit, and wrote the microcontroller code.<\/p>\n<p><a href=\"https:\/\/tstarling.com\/blog\/2013\/08\/season-clock\/season-clock-schematic\/\" rel=\"attachment wp-att-85\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-85\" title=\"Season clock schematic\" src=\"https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-schematic-600x355.png\" alt=\"Schematic\" width=\"600\" height=\"355\" srcset=\"https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-schematic-600x355.png 600w, https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-schematic-300x177.png 300w, https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-schematic.png 804w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>In-circuit programming made testing and debugging easy. I built the circuit on Veroboard.<\/p>\n<p><a href=\"https:\/\/tstarling.com\/blog\/2013\/08\/season-clock\/season-clock-vero-2\/\" rel=\"attachment wp-att-87\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-87\" title=\"Season clock veroboard layout\" src=\"https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-vero1.png\" alt=\"Veroboard layout\" width=\"423\" height=\"569\" srcset=\"https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-vero1.png 423w, https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-vero1-223x300.png 223w\" sizes=\"auto, (max-width: 423px) 100vw, 423px\" \/><\/a><\/p>\n<p>Blue lines are copper tracks, red lines are jumpers. Cyan marks the track breaks, which I etched out with a dremel engraving bit.<\/p>\n<p><a href=\"https:\/\/tstarling.com\/blog\/2013\/08\/season-clock\/season-clock-photo-2\/\" rel=\"attachment wp-att-89\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-89\" title=\"Season clock photo\" src=\"https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-photo1-600x450.jpg\" alt=\"\" width=\"600\" height=\"450\" srcset=\"https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-photo1-600x450.jpg 600w, https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-photo1-300x225.jpg 300w, https:\/\/tstarling.com\/blog\/wp-content\/uploads\/2013\/08\/season-clock-photo1.jpg 1224w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>I had to take the hands off to get the movement box open. The hands were made of metal barely thicker than foil, and it was necessary to use quite a bit of force to get them off the shaft. So I&#8217;m quite proud of myself for managing to save the minute hand and to get it back on to the shaft intact.<\/p>\n<p>It was somewhat scary pulling the movement apart and putting it back together again. It was necessary to take all the tiny nylon gears out to get to the motor connections. When I put the case back on, one of the gear axles wasn&#8217;t quite lined up correctly, and it bent through almost 90\u00b0. I bent it back into shape by hand, and it somehow still worked afterwards.<\/p>\n<p>The code is interrupt-driven. With a 32.768 kHz system clock in idle mode, the current draw was only 80\u00b5A, plus about 0.1\u00b5A average for driving the motor (3mA pulses with 0.004% duty cycle). So we can expect 3 years of battery life from a pair of AA alkalines.<\/p>\n<pre lang=\"C\">\/**\n * A driver for a standard battery-powered analogue clock, which will tick once\n * every 8766.15 seconds, so that the minute hand will complete a revolution once\n * per year. With the hour and second hands cut off, and appropriate artwork \n * attached to the dial, the minute hand will tell you what season it is.\n *\n * An ATtiny24\/44\/84 should be used, with a 32.768 kHz watch crystal attached\n * to XTAL1\/XTAL2. PA0 and PA1 are used as a virtual H-bridge.\n *\n * According to Silicon Chip March 2008, a suitable pulse is 13mA for 100ms. \n * With 3V battery power, that suggests a current-limiting resistor in the \n * vicinity of 230 ohms.\n *\n * For my continuous sweep wall clock, the multimeter says:\n *   * coil resistance = 560 ohm\n *   * frequency at either port = 8 Hz\n *   * duty cycle = 18.7% (implies 23.4ms pulse)\n *   * VDC = 0.3V (divided by 18.7% implies full swing of 1.6V)\n * \n * So that implies a 560 ohm resistor for a supply of 3.2V\n * Note: dial diameter 237mm.\n *\n * Timer0 is used for pulse duration timing. Timer1, in combination with the \n * counter variable, is used as the real-time clock.\n *\n * LFUSE must be set to 0xe6 to enable the external crystal.\n *\/\n#define F_CPU 32768\n#include &lt;util\/delay.h&gt;\n#include &lt;avr\/io.h&gt;\n#include &lt;avr\/sleep.h&gt;\n#include &lt;avr\/power.h&gt;\n#include &lt;avr\/interrupt.h&gt;\n#include &lt;avr\/wdt.h&gt;\n\nstatic long counter = 0;\nstatic enum {\n\tPULSE_POSITIVE,\n\tPULSE_NEGATIVE\n} nextPulse;\n\n\/\/ 0.023 seconds with prescale 64\n#define TICK_DURATION (short)(0.023 * F_CPU \/ 64)\n\n#ifdef TEST_MODE\n#define PERIOD_FACTOR_1 (unsigned int)(F_CPU \/ 16)\n#define PERIOD_FACTOR_2 1\n#elif CLOCK_WAS_1HZ\n\/\/ Tick with period 50026*5742\/32768 seconds\n\/\/ 50026 * 5742 \/ 32768 happens to be very close to the number of hours in\n\/\/ a year. So our minute hand will cover one revolution in one year, with a \n\/\/ residue here of only 8ms (although of course the quartz crystal is not \n\/\/ that stable, or even calibrated correctly)\n#define PERIOD_FACTOR_1 (unsigned int)(50026.0 * F_CPU \/ 32768)\n#define PERIOD_FACTOR_2 5742\n#else \/* 16 Hz *\/\n\/\/ This is for continuous sweep movements that normally require 16 ticks per second\n\/\/ Tick with period 15845*1133\/32768 seconds.\n\/\/ For testing, a square wave will appear on PA3 with frequency 1.034017 Hz.\n#define PERIOD_FACTOR_1 (unsigned int)(15845.0 * F_CPU \/ 32768)\n#define PERIOD_FACTOR_2 1133\n#endif\n\nstatic inline void tick() {\n\t\/\/ Start the clock\n\tpower_timer0_enable();\n\t\/\/ Set up Timer0A to interrupt after the tick duration\n\t\/\/ Reset the counter\n\tTCNT0 = 0;\n\t\/\/ Enable output compare interrupt\n\tTIMSK0 |= _BV(OCIE0A);\n\t\/\/ Start the pulse\n\tif (nextPulse == PULSE_POSITIVE) {\n\t\tnextPulse = PULSE_NEGATIVE;\n\t\tPORTA |= _BV(PA0);\n\t} else {\n\t\tnextPulse = PULSE_POSITIVE;\n\t\tPORTA |= _BV(PA1);\n\t}\n}\n\nISR(TIM0_COMPA_vect) {\n\t\/\/ End the pulse\n\tPORTA &amp;= ~_BV(PA0);\n\tPORTA &amp;= ~_BV(PA1);\n\n\t\/\/ Disable the interrupt and the timer module\n\tTIMSK0 &amp;= _BV(OCIE0A);\n\tTCNT0 = 0;\n\tpower_timer0_disable();\n}\n\nISR(TIM1_COMPA_vect) {\n\t\/\/ Toggle the test signal\n\tPORTA ^= _BV(PA3);\n\tif (++counter &gt;= PERIOD_FACTOR_2) {\n\t\t\/\/ Cycle the stepper motor\n\t\tcounter = 0;\n\t\ttick();\n\t}\n}\n\nint main() {\n\twdt_disable();\n\tpower_adc_disable();\n\tpower_usi_disable();\n\n\t\/\/ Enable pullups for unconnected pins\n\tPORTA = ~_BV(PA0) &amp; ~_BV(PA1) &amp; ~_BV(PA3);\n\tPORTB = ~_BV(PB0) &amp; ~_BV(PB1);\n\t\/\/ Set direction for outputs PA0, PA1 and PA3\n\tDDRA = _BV(DDA0) | _BV(DDA1) | _BV(DDA3);\n\n\t\/\/ Set up Timer0 with prescale=64, but disable the clock initially\n\tTCCR0B = _BV(CS01) | _BV(CS00);\n\tOCR0A = TICK_DURATION;\n\tpower_timer0_disable();\n\n\t\/\/ Set Clear Timer on Compare mode\n\tTCCR1B |= _BV(WGM12);\n\t\/\/ Set clock source CLKIO no prescaler\n\tTCCR1B |= _BV(CS10);\n\t\/\/ Set the period\n\tOCR1A = PERIOD_FACTOR_1 - 1;\n\t\/\/ Enable interrupts\n\tsei();\n\tTIMSK1 |= _BV(OCIE1A);\n\t\/\/ Interrupt loop with idle mode between interrupts\n\tset_sleep_mode(SLEEP_MODE_IDLE);\n\twhile (1) {\n\t\tsleep_mode();\n\t}\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>My wife Angela wanted a clock for her birthday where its one and only hand would go around once per year. Sure, I can do that, I said. Angela chose a wall clock to modify, and chose artwork for the dial. I designed and built the circuit, and wrote the microcontroller code. In-circuit programming made &#8230;<\/p>\n<p><a href=\"https:\/\/tstarling.com\/blog\/2013\/08\/season-clock\/\" class=\"more-link\">Continue reading &lsquo;Season clock&rsquo; &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-84","post","type-post","status-publish","format-standard","hentry","category-electronics"],"_links":{"self":[{"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/posts\/84","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/comments?post=84"}],"version-history":[{"count":27,"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/posts\/84\/revisions"}],"predecessor-version":[{"id":243,"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/posts\/84\/revisions\/243"}],"wp:attachment":[{"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/media?parent=84"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/categories?post=84"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tstarling.com\/blog\/wp-json\/wp\/v2\/tags?post=84"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}