Stepper Substitute
The technology and science of timekeeping has an interesting history. Jeff gives an overview, and then shares the details of his project that uses a Microchip ATtiny45 MCU to replace the stepper drive circuitry that’s popular for quartz-based clock movements.
There is no escape from the passage of time. While we may not be aware of its passage while sleeping, we find it has continued on its merry way without our conscious awareness. Steadily it moves, and from our vantage point we see what was, live in the present and look toward what is to come. We have come to measure it in many ways—by day, month, year, a lifetime. Before clocks or calendars, it became apparent for survival that we needed to pay attention to time. The whole universe is under its spell, and it defines how we spend our lives.
Earth’s rotation on its axis accounts for our day and night. Earth’s trip around the Sun creates our seasons and our year. Early man had no concept of planetary action, but divided a day into watches. What? Yes, the Greeks began dividing the day into periods of duty—day watches and night watches. Later, canonical hours broke the watches into smaller periods of prayer. The book of hours identified which prayers were to be said at which hours. A day became 24 hours.
Since the Earth rotates 360 degrees each day, it rotates 15 degrees each hour. These 15 degrees can be further broken down into minutes (1/60 hour) and seconds (1/60 minute). What’s so special about 60? At the time, the sexagesimal system (base=60) was used to measure angles. And so, the minute became 1/60 of an hour (15 degrees of arc/60 minutes = 0.25 degree of arc/minute). Also, the second became 1/60 of a minute (0.25 degrees of arc/60 seconds = 0.004166 degrees of arc/second).
FYI: During the French Revolution, they tried restructuring the day into decimal time. The French hour was 1⁄10 of the day, and each hour was divided into 10 decimal minutes of 10 decimal seconds each. Fortunately, this bad idea didn’t survive.
The measurement of hours, minutes and seconds became tangible once we had a device that could present it accurately. Gearing easily divides a day into hours, minutes and seconds, but an accurate time base was an issue. That’s where TikToc—I mean tick-tock—comes in. Rising water in a container from a dripping source was most often used to drive the hands of a clock. The size of the drip orifice controlled the accuracy to about a fraction of an hour a day. Later, gravity was used again to produce an accurate escapement. This time, a swinging pendulum regulated the gear train’s movement. Readers who are mechanically inclined are encouraged to explore the evolution of the escapement.
NOT GOOD ENOUGH
The time required for our planet to rotate on its axis fluctuates daily, and the average time continues to decrease. To ensure our clocks reflect this, we must occasionally add a second to the time count. Our clocks then wait that second to give Earth the opportunity to catch up. Presently, this is done about every 1.5 years. An average Earth day is therefore about 0.002 seconds longer than 24 hours. The whole point here is that because our time is based on the Earth’s rotation, it isn’t exact.
— ADVERTISMENT—
—Advertise Here—
Technology has now “improved” the mechanical escapement, producing more accurate timekeeping devices thanks to the quartz crystal. Like the pendulum in a Grandfather Clock or a balance wheel in a wristwatch, the quartz crystal provides regulation of the 1 second time period used to drive the hands. The difference is in accuracy. The mechanical marvels are good to within about 2 minutes a month. The crystal’s accuracy can improve that to about a second a month. And today’s crystals are trimmed by laser to vibrate at 32,768Hz ±0.06Hz.
The first digital watches did not have hands! Since these require a battery to run the quartz crystal’s oscillator, it only takes a bit more circuitry to enable the time to be calculated and presented using LED displays (Figure 1) [1]. No more hour hands, minute hands or second hands. Or so we thought. The integration of a mechanical movement with quartz precision gave the public the visual interface they were so familiar with. (In watch jargon, a “movement” is the timekeeping mechanism of a watch or timepiece.) While these couldn’t compete with the lower-cost “digital” watch, the “analog” watch with a quartz movement has now reclaimed its market share.
How does the precision vibration relate to our tick-tock (second)? If we divide this number (32,768) by two 15 times (215) we get 1Hz. With an adequate pulse to drive the coil of a tiny stepper motor at 1Hz (or other period) it can synchronously move the gear train. If designed for 1Hz, the movement moves 1 second per pulse. A sweep movement can be had by using multiple of pulses with a gear reduction of the same multiple. The steps will therefore be so small they will give the impression of sweeping.
The majority of clocks hung in homes today have quartz movements. They use one “AA” battery, and display time to a world of different faces. You can choose from numerous different looks—from the normal to bizarre (Figure 2). The quartz movements are prepackaged in small plastic housings that can be mounted to a unique face with one simple hole. A variety of different clock “hand” styles are available in different colors to really personalize your finished clock.
12-HOUR STANDARD
Most clocks seen today are standard, 12-hour clocks. They go through their complete movement twice a day—AM and PM. The second, minute and hour hands are geared for the “60:1 / 720:1” format. In other words, for each 60 rotations of the second hand, the minute hand will rotate once, and for each 60 rotations of the minute hand, the hour hand will rotate 30 degrees or 1/12 of a complete rotation (one half day).
Other timekeeping periods may be of interest: solar (24:00:00), lunar or tidal (24:50:28), seasonal (91 days 6:00:00), zodiac (30 days 10:25:00), sidereal (23:56:04), Martian (24:39:36), DOW (7 days 00:00:00) and DOM (x days 00:00:00).
Based on some work by Simon Inns [2], Akafugu Corporation [3] and Geppetto Electronics [4], my column this month is a fun look into some scientific and wacky pulse trains. The circuit presented here is for experimenting with a Microchip Technology (formerly Atmel) ATtiny45 microcontroller (MCU) to replace the stepper drive circuitry used in a popular quartz clock movement. Geppetto Electronics has a pre-programmed PCB available, which can be ordered with or without the quartz movement. Look for Nick Sayer’s PCB files [5] and Firmware files [6] in his original project on hackaday.io [7].
ALL ABOARD THE PULSE TRAIN
Let’s first look at the basis for driving the clock’s stepper motor, so we can accurately control the hour hand’s movement. Figure 3 shows the Lavet-type stepper motor, consisting of a large coil wound on one leg of a long, U-shaped field director, into which a tiny geared armature is placed. Due to the shape of the field poles, the armature, which is a magnet, is attracted to the metal pole slightly off center, while the poles are not energized (have no magnetic field). When a pulse to the coil magnetizes the poles, this field is not aligned with the armature’s position, and causes it to repel (rotating) toward the opposite pole (always in the same rotational direction.) Now, again with no magnetic field, the armature is attracted to the pole itself, slightly past the point where the pole’s energized field had been. The coil now requires a reverse polarity pulse to repel the armature in its in its forward journey to its original location. A good explanation can be viewed on YouTube [8].
I placed my oscilloscope’s dual inputs across the coil, so I could see the pulse referenced to ground of the 1.5V battery. Figure 4 shows alternating pulses on the coil, which come from two drive pins. By alternating pulses on the two drive pins to the coil, a magnetic field is created—first in one polarity, and then the opposite—at precise intervals of 1Hz. Thus, the armature makes a complete rotation every 2 seconds. Each pulse is approximately 33ms.
— ADVERTISMENT—
—Advertise Here—
A quartz movement only requires the oscillator/amplifier and binary divider sections for a 1Hz time base to run the stepper motor and produce the 12-hour format we are so used to today. It’s overkill to use an MCU here, but if we want programmable control of the time base, it is a worthwhile path.
Let’s look at Nick Sayer’s approach using an ATtiny45 MCU. Like all low-pin-count MCUs, the same pins that are used to program the device are also used for your I/O. The ATtiny45 uses the 6-pin SPI connections for programming. Designers must be careful with the functions they put on these pins, or they may not be able to do in-circuit programming. While many MCUs have internal oscillators stable enough for many applications, we need the precision of using an external 32kHz crystal. The circuit I used to experiment for this column is shown in Figure 5. Note that the standard ATtiny will run down to 2.7V, and the “V” version will operate down to 1.7V. This will be an issue, since the battery for the clock is 1.5V (when new)!
To resolve this issue, Nick used a XC9140 Series Step-Up Synchronous PFM DC-DC converter from Torex Semiconductor to produce a constant 3.3V for the ATtiny. This converter can start with battery voltages as low as 0.9V, which is about half that of a 1.5V alkaline battery. I decided to use an 18650-style Li-ion battery. Although it is around 50% larger than a “AA” and won’t fit into the “AA” slot of the quartz drive enclosure, it has the voltage to run the MCU without a DC-DC converter, and will last far longer than any alkaline battery. The series resistors reduce the higher-than-normal voltages from the MCU down to the 1.5V that would normally be on the coil. The diodes are protection from the reverse currents of the coil’s collapsing magnetic field.
C IS FOR CLOCK, CODING, CRAZINESS
Let’s start with a little look at the C program that is used to provide the basic functions needed for this application. The three basic functions are doSleep()
, doTick()
and normal()
. Figure 6 is a flow diagram for these functions. The doTick()
function handles applying a pulse to one of the output pins; the output will alternate pins for each Tick. doSleep()
determines if we can go to sleep or we need to catch up (more on this in a bit). normal()
creates the kind of pulse train we want (more on this later).
The flow diagram shows how the routines are related to creating a pulse train for the stepper motor.
Things begin with several initializations which include the time-base interval interrupt. While we need a 1Hz time base, the interrupt will be 10 times faster. This will give doTick()
a time-base resolution of 100ms. The timer uses the oscillator input with a pre-scaled divide-by-64, so the timer counts at a 512Hz rate (32,768Hz / 64 = 512Hz). To get down to 10Hz, count to 51 four times (51 × 4 =204), and then count to 52 (204 + 52 = 256). While doing this twice produces 10 unequal interrupts, it averages out to 1Hz.
So, we’ve set up all our variables, constants and interrupt timer, and the sleep mode is set to “Idle” to keep the oscillator running. All unused peripherals are turned off, and the interrupts have been enabled. We are now ready to go to sleep, knowing that we’ll be sucking minimum juice until we’re awakened by the next timer overflow in just about 100ms.
Note here that normal()
is the control function. It handles the timing of the pulses—in this case, 1 Tick every 10 Sleep periods. The 100ms interrupt timer takes care of waking the processor up from the Sleep instruction. During these Sleep periods, which is most of the time, a minimum of current drain is put on the battery. The function base()
, handles all the setup and defines the doTick()
and doSleep()
functions that will be used by any control function that replaces normal()
. doTick()
creates a 35ms pulse on the mechanical stepper. The normal()
function creates a standard 12-hour clock.
TIDE CLOCK
How else might this technology be used for some non-standard timekeeping applications? As a child, my favorite adventures were those days when Dad would take us kids to Misquamicut beach (Rhode Island.) for the day. I learned of Mother Nature’s strengths, while endlessly creating sand castles, none of which would ever hold up to the tide’s mighty power. I began to realize that high and low tides did not follow the earth’s day and night cycle, and each day we spent at the shore brought on what seemed to be random illogical tide flows. I noticed that high and low tides seemed to be affected by the Moon. In those days (the 1960s), the Moon was all over the news. Man was actually going to travel there! The country was unified by a common desire to be the first to land on the Moon.
If we had no Moon, the water on Earth would be pulled down by Earth’s gravity equally all over the planet, and up toward the Sun on the side facing the Sun. This tug by the Sun—though it cannot deform the Earth—does draw the bodies of water ever so slightly toward the Sun, raising the level on the sunny side of the Earth and pulling it away from the dark side. So, we might see tides that are closely related to the standard 24-hour day.
Add the Moon into this mix, and its mass has a large effect on the Earth’s bodies of water. Now the sum pull on the waters is not directly toward the Sun, but shifts with the Moon’s position relative to the Sun. The shifting water piles up, creating what we call high tide, while those places from which the water has been drawn see low tides. While this is not true for all places on Earth, the Misquamicut, RI beaches have high and low tides twice a day—about every 12 hours and 28 minutes.
Builders of sand castles and, more importantly, all individuals who make a living from the coastal maritime economy, live by the tidal highs and lows. Those who work this schedule every day certainly know the periodic nature of the tides. We landlubbers need a little help. If we can stretch time such that a day is actually 50.5 or so minutes longer, then the hour hand will point to high tide twice a day instead of noon and midnight. You can replace the clock’s hour numbers with high tide (straight up) and low tide (straight down) points, and the hour hand will be happy to point these out.
To accomplish this, we need to slow each tick down. If one “Sleep” interrupt is added to the normal 10 (a total of 11), that would make a tick every 1.1s or 10% slower than normal. We need to add 50:28 or 3,028 seconds to a day, 28 seconds + (50 minutes × 60 seconds/minute) = 3,028 seconds + 86,400 seconds/day, for a total of 89,428 seconds.
By adding in an extra Sleep (tenth of a second) here and there, the time between “Ticks” becomes slightly longer. We need to spread them out 3,028 times over the 86,400 seconds of a day. What part of a day is 3,028 seconds? It’s every 28.5336856010568 seconds (86,400 seconds / 3,028 seconds = 28.5336856010568 seconds. Because we’re dealing with tenths of a second (one interrupt), if we add an extra Sleep every 2.8 seconds, we would get 86,400 / (2.8 × 10) = 3,086 extra seconds. If we add an extra Sleep every 2.9 seconds, we would get 86,400 / (29 × 10) = 2,979 extra seconds. To hit our mark, we need something between 2.8 seconds and 2.9 seconds. We will do 28 for part of the time and 29 for the rest. The decimal turns out to be 3,028 seconds × 0.5336856010568 = 1,615.999999 or 1,616/3,028— reduced to 404/757.
The tidal.c
function defines the clock drift as…
// This is the whole number
#define BASE_CYCLE_LENGTH (28)
// This is the fractional numerator
#define NUM_LONG_CYCLES (404)
// This is the fractional denominator
#define CYCLE_COUNT (757)
… so that the appropriate number of sleep times are added to the original 10 “Sleep”/”Tick”. This fools the clock mechanism into thinking 24 hours have passed, when in actuality, 24 hours, 50 minutes and 28 seconds have passed!
— ADVERTISMENT—
—Advertise Here—
Nick Sayer added a whole bunch of files for other clock timings that you can use to make some pretty esoteric clocks. One of my favorites is tuney.c. This will drum out the rhythms of various random tunes as an hourly chime. To do this, he Ticks rapidly, then Sleeps for each duration of the notes/rests of each tune, giving the clock a “rum-tum-tum” sound by the second hand going crazy beating out the rhythms. The Tick and Sleep timing is such that the average is 1 tick/second—therefore, the clock never loses or gains due to this chime. Pretty slick!
WAITING FOR THE SECOND HAND
I wondered what I could do that might be a bit different. I remember that back in school, during those classes I despised, I would literally watch the second hand on the wall clock, waiting for it and the minute hand to reach 12, denoting the end of class. It seemed to take forever. Hmm, could I make this a reality?
Imagine time initially speeding by, but by the end of an hour, it s-l-o-w-s d-o-w-n t-o a c-r-a-w-l! At the beginning of an hour, I Tick 10 times a second. At the end of the hour, I Tick every 10 seconds. I just had to figure out what to do in between. I decided to use two tables (Listing 1)—one as Tick/Sleep ratio, and one for how many times to do each ratio. I wanted my ratio table to be between 1 (100ms) and 100 (100 × 100ms – 10s). The repeat table begins with a Tick every tenth for 407 times. Then a Tick every 2 tenths for 361 times. That makes the first minute fly by in about 6 seconds. At the other extreme, the last second takes 10 seconds! The trick is that the total Ticks must equal 3,600, and the total Sleeps must equal 36,000 for this to take exactly 1 hour.
Listing 1
Code shows the two tables I used—one as Tick/Sleep ratio, and one for how many times to do each ratio.
// Ticks range from (1) 1 Tick every 1/10 second to (100) 1 Tick every 10 seconds
const unsigned char NumberOfTenths_Table[] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 80,
91, 92, 93, 94, 95, 96, 97, 98, 99, 100
};
// Each NumberOfTenths_Table[] entry is repeated x times such that the total is 3600 Ticks in an hour
const unsigned char NumberOfTimes_Table[] =
{
407,361,320,290,260,230,200,180,160,140,
120,100, 90, 80, 70, 60, 50, 45, 40, 35,
30, 25, 20, 18, 15, 12, 11, 10, 9, 9,
8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
5, 5, 5, 5, 5, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
int tenths;
int times;
/
void loop()
{
while(1)
{
// A new hour
for(times = 0; times < sizeof(NumberOfTenths_Table); times++)
{
// Do this x times
for(tenths = 0; tenths < sizeof(NumberOfTenths_Table); tenths++)
{
// Set the second Tick from 1/10 to 10
if(tenths = 0)
{
// Do a Tick on the first tenth
doTick();
}
else
{
// Sleep for any other tenths
doSleep();
}
}
}
}
Note that the NumberOfTenths_Table
has two entries of “9.” This tweaks the counts to come out correctly. I used an Arduino to check the totals. Minor modifications added the two variables…
long totalticks = 0;
long totaltenths = 0;
and a print routine to give me the totals after a run through the routine.
Total Ticks: 3600
Total Tenths: 36000
So, there it is, the dread of my school days come to reality. I can enjoy this today and just sigh as I ponder our perception of time.
I used Microchip Technology’s (formerly Atmel’s) Studio 7 online compiler to put this all together and program it into my prototype board (Figure 7), using a USBtinyISP SPI programmer (available from Adafruit). After verifying the signals on the scope, it was time to put all of this into play. I put the same code into one of Nick’s PCBs pre-mounted on the clock mechanism. Since I began all these shenanigans on the hour, I set the hands of the movement to the upcoming hour and patiently waited for the “real” clock to reach the hour before popping in the battery. Immediately, the second hand began spinning around. Ahh, success.
I placed a couple of opposing LEDs on the pulse output connector of my prototype, to give me a visual indication of the pulses being produced by my program. The LEDs alternate because of the positive and negative pulses produced by the differential output of PinA and PinB.
SCHOOL’S OUT FOREVER
Alice Cooper’s slightly destructive rant is one of their great songs. As I learned after the fact, school is something one should take seriously, especially while the mind is still forming. Today I spend a lot more time reading to expand my knowledge base. It’s not formal but practical. Whatever you do, make sure you add in the appropriate amount of fun. It does not affect the passage of time, but it does have an effect on your quality of life. Too much to do, so little time, depending on which clock you are watching!
RESOURCES
References:
[1] Patent for solid-state quartz watch
https://patents.google.com/patent/US3863436A/en?oq=3863436
[2] Simon Inns’ post on Vetinari’s Clock (driving a quartz clock movement).
www.waitingforfriday.com/?p=264
[3] Akafugu Corporation product on reproducing a Lord Vetinari clock.www.akafugu.jp/posts/products/vetinariclock
[4] Geppetto Electronics www.geppettoelectronics.com
[5] Nick Sayer’s PCB design files (Crazy Clock: A replacement controller for Lavet stepper clock movements).https://hackaday.io/project/5880-crazy-clock#menu-files
[6] Nick Sayer’s Firmware files for Crazy Clock— An ATTiny85-based, variable-rate (with long-term accuracy) clock movement.www.github.com/nsayer/Crazy-Clock
[7] Nick’s original project www.hackaday.io/project/5880-crazy-clock
[8] YouTube video with explanation of how a Lavet-type stepper motor works:
Adafruit | www.adafruit.com
Microchip Technology | www.microchip.com
Torex Semiconductor | www.torexsemi.com
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • NOVEMBER 2021 #376 – Get a PDF of the issue
Sponsor this ArticleJeff Bachiochi (pronounced BAH-key-AH-key) has been writing for Circuit Cellar since 1988. His background includes product design and manufacturing. You can reach him at: jeff.bachiochi@imaginethatnow.com or at: www.imaginethatnow.com.