Tuesday, August 5, 2014

Crazy clock controller

We engineers are nothing if not un-original.

This item intrigues me.

When something like that intrigues me, the most prominent thought I have is, "could I do that?" Maybe that's what makes me a Maker. I dunno.

But you know what? I think I can do that. Not only that, but I think I could make a little tiny replacement controller board so that anyone could retrofit any similar clock to make it crazy (and yet, still keep accurate long-term time).

Well, how do those clock movements work?

Wikipedia has the answer. Well, that, and this guy.

In short, an ATTiny85 can easily do this. You fuse it to run on a crystal, but you also fuse it to add the divide-by-8 so that the actual clock speed is more like 1 MHz (but an accurate 1 MHz). To make the hands tick once, you first pulse one of the solenoid leads high, and then pulse the other one high.

To do the craziness, loop() will do something like this:

Pick a random number of seconds from 2 to 30. Pick a random factor from 1 to 5 (picking random numbers is actually going to be the hardest part of this project. Fortunately, there's no need for cryptographic levels of entropy or anything).

The concept is that you're going to take the chosen interval period and speed the ticks up by the given factor. Then you're going to just wait until the interval elapses and then do it again. So the clock might tick 4 times in one second, then pause for 3 seconds, then tick twice normally, then tick 20 times in 2 seconds and then stop for 18.

The goal is to just replace the controller board, and most of those clock movements take a single AA battery. You can't run an ATTiny on 1.5 volts, so an NCP1402 will boost it  up to 3.3. Those work all the way down to 0.8 volts, by which point a AA is well and truly dead. By using a higher than normal voltage, we can increase the solenoid series resistors, and hopefully the spikes will have less impact on the supply voltage.

And, of course, with SMD construction, this board can be made really, really small. In fact, the largest feature on the PCB will probably be the ISP footprint. Hopefully I can stick it somewhere on the bottom out of the way.

The sketch:
#include <arduino.h>

// clock solenoid pins
#define P0 0
#define P1 1
#define P_UNUSED 2


// pulsing params
#define PULSE_WIDTH 50
#define PULSE_SEPARATION 20

static void doTick() {
    digitalWrite(P0, HIGH);
    delay(PULSE_WIDTH);
    digitalWrite(P0, LOW);
    delay(PULSE_SEPARATION);
    digitalWrite(P1, HIGH);
    delay(PULSE_WIDTH);
    digitalWrite(P1, LOW);
    delay(PULSE_SEPARATION); //insure they don't pile up against each other
}

void setup() {
    pinMode(P_UNUSED, INPUT_PULLUP); // power savings over letting it float
    pinMode(P0, OUTPUT);
    pinMode(P1, OUTPUT);
    digitalWrite(P0, LOW);
    digitalWrite(P1, LOW);
}


void loop() {
    unsigned long intervalStart = millis();
    unsigned int intervalLength = random(2, 31);
    unsigned int intervalFactor = random(1, 6);

    unsigned long tickLength = 1000 / intervalFactor;

    for(int i = 0; i < intervalLength; i++) {
        unsigned long tickStart = millis();

        doTick();

        unsigned long elapsedTime = millis() - tickStart;
        delay(tickLength - elapsedTime);
    }

    unsigned long elapsedTime = millis() - intervalStart;
    delay(intervalLength * 1000 - elapsedTime);
}

No comments:

Post a Comment