Sunday, August 17, 2014

More crazy clock work

I actually tested the firmware with a 10 based crystal (2.000 MHz). Firstly, the power savings over 4.096 MHz wasn't really worth writing home about. Saving more power would probably require further reducing the system clock frequency from 500/512 kHz, but if you do that, then you can't use an ordinary AVR programmer with an 400 kHz SPI clock. Surprisingly, the ATTiny85 retains the programmed clock divider during RESET rather than reverting to the fused divider value. So just for my own convenience, I'm sticking with 500/512 kHz, which still results in a single AA battery lasting somewhere around 6 months, if I'm doing the math right.

Anyway, after finding and fixing a minor bug, I've confirmed that the long term accuracy with a ten based crystal instead of a 2 based crystal is still good, so my fractional OCR0A mechanism works. Yay!

However, in looking at the pulse timing on my oscilloscope, I discovered something that I think I'll have to address.

Whenever you are using semiconductors to switch a large inductor on or off (this applies with motors, relays, solenoids... anything with a big coil), you need to deal with the coil collapse voltage that will be induced the moment you switch the transistor off. The usual solution is a reverse-biased diode across the coil, which will allow the diode to conduct when the coil commutates and prevent a large negative voltage from appearing at the transistor.

What I saw on the scope was that despite the presence of the diode, there was still a -1 volt pulse when the coil was switched off. Turns out, I'm using a 1N4148, and the forward voltage drop is about 1 volt.

The issue I see is that the absolute maximum section of the ATTiny85 datasheet says that the limit for any pin is -0.5 volts.

Now, to be fair, I think Atmel really means for that to apply to pins configured as inputs. It's unclear what impact there might be to an induced negative voltage spike like that on an output pin set LOW.

This was never an issue before because in most cases, I've used a transistor to switch the power on and off, and in a typical low-side NPN switching arrangement, the flyback diode is intended to keep the voltage spike under the collector-emitter breakdown voltage, which is always much higher than any reasonable diode forward voltage rating.

Fortunately, the solution is straightforward - pick a better diode. A Schottky diode can be had with a forward voltage of only 0.5 volts, and they make them in the same SOD-323 footprint. It may not - strictly speaking - be necessary to cut that spike in half given that the pin is configured as an output rather than an input, but it's probably good engineering anyway.

Also, I've added another firmware option. This one is a bit more prankish. It runs 10% fast for 12 hours, then 10% slow for 12 hours. It makes the days just fly by! For this one, it actually matters when you put the battery in. The controller has no idea where the actual hands on the clock are pointing - it's just a pulse source. So when the battery goes in, that marks the start of the 12 hour fast period.

EDIT: I asked the flyback diode question over on StackOverflow and it appears that this is not going to be a big deal. The worst case scenario is 1 volt going through a 100 ohm resistor, which would only be a potential of 10 mA on pins designed to source or sink up to 40 mA each.

Saturday, August 16, 2014

Crazy Clock user guide

This page is the permanent home for the Crazy Clock user's guide. It will be updated whenever changes are made. The current version of the board is v0.2. The board history:


  • v0.1 - Prototype
  • v0.2 - Changed crystal to HC-49 through-hole footprint and reduced size
The crazy clock comes as either a bare controller board which you can use to retrofit an existing clock movement or as a complete movement with the crazy clock controller installed in place of the original (boring) controller.

To retrofit an existing clock movement, carefully disassemble the movement and remove the stepper coil and controller board, which should be a single assembly that can be easily removed. The board should be on the bottom and there should be two bare contact patches which touch two contacts that come from the battery. Two other points on the board should be soldered (directly or indirectly) to the two ends of the coil wire. For best results, do not disturb the soldered joints of those wires. Instead, use a Dremmel or an Exacto knife and cut the traces leading away from the two coil wire solder patches and the two battery contact patches. Solder 30 gauge wires to each. For best results, use a dab of hot glue to secure the wires to the board as a strain relief. Reinstall the board, routing the wires carefully to avoid interfering with any moving parts of the movement. Connect the ends of the wires to the battery and clock terminals on the crazy clock controller board. Tuck the controller board in an out-of-the-way spot inside the movement insuring that neither it nor any of the wires will interfere with any of the movement's moving parts. Alternatively, you can route the wires outside of the movement enclosure and use foam tape to secure the controller externally (doing it this way is less stealthy, but makes reprogramming the controller much easier). There's an instructional video that shows the major points of the process.

The crazy clock will run for around 6 months or so on a single AA battery, depending on the particular clock movement into which it's installed. Simply replace the battery when the clock stops. Other than the changes made to how the clock operates, actual use of it is exactly the same as the original movement. You set the time by rotating the set knob and replace and install the AA battery in the same manner as before.

Depending on which firmware you selected, your clock will behave differently from a normal clock, but should still keep average time accurate to within a minute per month (20 ppm), so long as the clock is kept near room temperature. When exposed to extreme temperature swings, you can expect the accuracy to suffer.

If you change your mind, you can re-flash the firmware. The firmware files are available at the Crazy Clock repository on Github. You will need a pogo pin programming adapter and an AVR programmer. You'll also need the Arduino IDE, and you'll need to add ATTiny support to it. If you want to build your own Crazy Clock controller from scratch, you'll need to fuse your ATTiny85 before programming it. The correct fuse settings are low:0xFD, high:0xDF and extended:0xFF.

Theory of operation

The battery is connected to a boost converter that will increase the voltage to a regulated 3.3 volts from whatever voltage the battery is giving out all the way down to around half a volt or so. The boosted voltage is fed into an ATTiny85 with a 4.096 MHz crystal.  The firmware divides that by 8 for a system clock of 512 kHz. 512 kHz is the minimum frequency selectable that will still allow a normal AVR programmer to program the ATTiny (at an SPI clock of 400 kHz). Timer 0 is set up for a prescale of 1024, for a counting rate of 500 Hz and then is set to count from 0 to 49 and interrupt the CPU. These interrupts will therefore be at 10 Hz. The interrupts will be used to wake the CPU from sleep mode, which will minimize power consumption. The clock marks time by sleeping and then being woken up every 10th of a second.

Alternatively, the circuit can be built with a 4.000 MHz crystal instead of 4.096 MHz. In this case, the system clock will be 500 kHz and the divide by 1024 prescale value will result in a fractional count frequency. The firmware will need to toggle the CTC timer limit register between 48 and 47 to maintain a nominal 10 Hz interrupt rate.

The clock movement is based on a lavet style stepper motor. To make the second hand tick once, you must apply pulses across the coil, but each must be the opposite polarity of the last. This can be accomplished simply by pulsing one of two digital pins high (keeping the other grounded) and connecting both to the coil. To protect the controller from coil collapse voltages, a reverse biased diode to ground from each coil wire is present. Series resistors on each wire also reduce the voltage since the original working voltage of the system was the battery's 1.5 volts instead of 3.3.

Schematic



Friday, August 15, 2014

A square peg in a round hole

The initial design of the crazy clock board uses a 4.096 MHz crystal because the prescaler combinations that are available are all powers of 2, and 1024 is the best one for the timer prescaler. But we want a 10 Hz basic interrupt source, and I just sort of gave up on trying to do that math.

But in figuring out the Martian clock's need to insert what amounts to a very whacky number of extra cycles, I remembered some work I did a long time ago in designing a custom programmable PLL circuit.

A lot of the programmable PLLs out there are designed with a special intermediate output to control a  prescaler that can do both divide-by-n and divide-by-n+1. So you can, for example, get a divide-by-5/divide-by-6 prescaler and your PLL will have a very low lock frequency, but still have a very minute tuning resolution because the divide ratio can effectively include fractions.

I used that to insert 99 extra counts for every 3600 by inserting an extra every 37 counts for 36 cycles, then every 36 counts for 63 cycles. 37*36+36*63 = 3600, and 36+63=99. And 24 hours becomes 24:39:36 and you're suddenly on Mars.

Well, could the same thing be done to let the basic mechanism work with a 2 MHz crystal? I can't find 2.048 MHz crystals, but a 2 MHz crystal might further reduce power consumption (going from 16 MHz to 4 MHz cut power consumption roughly in half).

Well, 2 MHz with a divide-by-4 prescaler is 500 kHz. That is, more or less, a match for the prototype's system clock. If we then set up timer 0 with a divide by 1024 prescaler, then what do we use for the CTC value?

500 kHz divided by 1024 is 488 + 9/32. Or put another way, to get 10 Hz, it's 48 and 53/64s. So if we set the CTC top to 49 for 53 cycles, and then 48 for 11, that solves the problem. The fact that some 10 Hz intervals will be 2.048 µS longer than others will be utterly insignificant.

All we have to do is replace sleep_mode() with calls to...

#define CLOCK_CYCLES (64)
// Don't forget to decrement the OCR0A value - it's 0 based and inclusive
#define CLOCK_BASIC_CYCLE (48 - 1)
#define CLOCK_NUM_LONG_CYCLES (53)

void do_sleep() {
  static unsigned char cycle_pos = 0xff; // force a reset

  if (cycle_pos == CLOCK_NUM_LONG_CYCLES)
    OCR0A = CLOCK_BASIC_CYCLE;
  if (cycle_pos++ >= CLOCK_CYCLES) {
    OCR0A = CLOCK_BASIC_CYCLE + 1;
    cycle_pos = 0;
  }

  sleep_mode();
}

Turns out Mouser has a 2 MHz crystal that conveniently fits in the footprint of the prototype board and even has a 10 ppm tolerance... but it's backordered until October. :(

Thursday, August 14, 2014

MicroBoost semi-failure

The 0.2 version MicroBoost boards came, and although they now fit properly in the Altoids gum case look-alike from Adafruit, the diode and MOSFET get super, super hot when charging an iPad. It still works just fine charging at 500 mA, but it looks like it's just not going to be able to do an amp.

I could use an B330LA-E3/61T and a SI3442CDV-T1-GE3 without changing the board. That MOSFET is the compliment to the part I use in Pi Power, and that's a buck converter capable of 2A of output power, so that gives me a good vibe. But I'm just not sure I'm all that interested.

Wednesday, August 13, 2014

One more crazy clock... the true Vetinari clock

The crazy clock repo now has a total of five different firmwares from which to choose. The last one is what I believe is as close as we're going to get to Terry Prachett's vision.

This clock ticks normally, except that about half the time it will tick after 1.1 seconds instead of 1.0 seconds. Once it's gathered up 10 "extra" tenths of a second, it will instead perform a "stutter" tick, ticking twice. When it's ticking normally, the extra tenths of a second are imperceptible, and the clock's rhythm is kept undisturbed so far as can be seen or heard. But the stutter ticks utterly wreck the natural rhythm and force your brain to restart. And they come randomly anywhere from 10 to 30 seconds apart. Frequent enough to be noticed, but infrequent enough to re-establish the natural rhythm between them.

Meanwhile, the original "crazy clock" firmware seems to still lose around a half an hour a day. That's still so much that it has to be a bug. I'm going to pore over the code once more to see if I can figure out what's wrong. But while I'm doing that, I'm going to run this firmware for a while and see if it's accurate. If it is, then that at least confirms that there isn't a hardware problem (my biggest fear is that the clockwork I'm using is somehow designed to be ticked inaccurately in a particular way, which would make a custom firmware basically impossible).

If I can confirm that the hardware works, there's one more clock I might write... The Huey Clock. It will beat twice in two seconds with a heartbeat rhythm. It might wind up being to slow and boring, but we'll see.

Tuesday, August 12, 2014

More crazy clock styles

Some more ideas on other ways to make a clock crazy (but, of course, still keep perfect time);

  1. The wavy clock. Frequency proportional to a sine wave. That one sounds like fun, actually. It'd probably have to be table-driven. No sense doing actual floating point on a battery powered ATTiny.
  2. The lazy clock. Pick a random number of seconds and just stop. Then tick at 10 Hz until you catch up.
  3. The zany clock. Pick a random tenth-of-a-second within each second for the tick.
Anybody have any others?

Crazy clock problems

It's not going spectacularly well.

The problem at the moment is accuracy. The clock is gaining about one extra hour in 8. That's just got to be a software bug of some sort. It's just inconceivable that a crystal oscillator could be 12.5% off, even if the loading caps aren't right.

I thought I found a fencepost error last night, but oddly that didn't seem to make a difference, and I'm not sure why not.

EDIT: Figured it out.

It was a different sort of fencepost. If you take two periods of 1/2 and double time and add them together, you get 5/2 - which is 20% fast. What you want to do is add 1/2 and 3/2 together to get 4/2, which is the right answer.

It turns out, however, that in my judgement the result is just a hair too subtle. So instead, I'm going with 1/3 time and 5/3 time. That works out nicely, since 5/3 time is 6 pulses out of 30, which is nice division.