Wednesday, August 27, 2014

µBoost user guide

This is the permanent spot for the µBoost user guide.

The µBoost is a battery powered USB power supply. It can supply up to 1A @ 5V from 3 primary cells (AA, C or D) or up to 500 mA from 2 primary cells.

You can use any supply voltage as long as it is lower than 5 volts. That means that you can use a LiPoly, NiCd, NiMh or any other chemistry you like.

Use of primary cells at more than 1A of current draw is not recommended. The batteries' internal resistance will cause them to get quite hot. Additionally, the higher the current draw, the less energy the batteries will deliver before they die (the extra energy is lost as heat). This is not a problem with most secondary battery chemistries, such as NiMh, Lion or LiPoly. If you wish, you can add a battery charger in parallel with the battery and µBoost.

The quiescent current of the converter (that is, its consumption with no load) is around 140 µA, which means that without being used, a set of AA batteries would last around 2 years.

The lower the input voltage, the hotter the MOSFET, diode and inductor will get during high current operation. It is not recommended to pull 1A with a 3 volt (2 battery) supply. Even if this weren't excessive switch current for the MOSFET, it would require pulling too much current from the primary cells than is good for them. If you heat up primary or secondary cells they can leak or explode.


Theory of operation

The µBoost is built around an NCP1450 boost converter controller with an external MOSFET switch. Because the switch is external, the controller itself has no limit on how much current it can switch (or supply). The MOSFET itself has a maximum drain current rating of a massive 8 amps, but in a boost converter arrangement the switching current is generally much higher than the output current rating. The same is true of the Schottky diode, which is rated at 3 amps and a maximum forward voltage drop of 0.5 V and the inductor, which is rated for over 2 amps.

A boost converter works because an inductor resists a change in the current flowing through it by generating a voltage. The inductor is connected between the line and load. Immediately after the inductor is a switch between the inductor's output and ground (in this case, the switch is the MOSFET). When the switch is closed, the inductor is connected across the input voltage, and it is effectively "charged." When the switch is opened, the current flow through the inductor is interrupted. The inductor attempts to "correct" this state of affairs by generating a high(er) voltage. That voltage passes through the diode to the load. When the switch is closed, the diode is reverse-biased and blocks current flow the "wrong" way from the load. The output filter capacitor supplies the load during this time.

The two data lines have resistor voltage dividers. These dividers are set to provide a constant voltage to the data pins. These voltages tell Apple iDevices the ampacity of the charger. The spec for these voltages is unpublished, but was discovered by the good folks at AdaFruit.

The only difference between the 500 mA circuit and the 1A circuit is the high side D+ resistors. It is 75k for 1A of charge current and 43k for 500 mA.


Schematic

Tuesday, August 26, 2014

Low power breakthrough

I've made a few battery powered projects since I've started, and the one constant in all of them is that none of them had a power switch. All of them (that had a microcontroller), went to sleep and used either a button interrupt or a timer to wake up again.

I've discovered that all of this time I was missing a crucial power-saving step.

One of the things I'd been doing in setup() was turning off all of the excess peripherals in the PRR - the Power Reduction Register. It turns out, however, that this is insufficient to turn the A/D converter off completely. You also must (first) clear the ADEN bit in ADCSRA. Not doing so wastes around 250 µA. It doesn't sound like a lot, but for the blinky earrings, which are powered by a CR1225, that is enough to kill the battery in about a week rather than allowing it to sit powered off basically for the shelf life of the battery. In the Crazy Clock, it's enough to reduce the (estimated) battery life from 18 months or so down to 3.

So... Before you put an AVR to sleep, clear the ADEN bit in ADCSRA and then set as many bits as you can in PRR.

Friday, August 22, 2014

Measure with a micrometer, mark with chalk, cut with an axe.

I happened to see a link to this from Dave over at eevblog. TL;DR, it's a 5 ppm mechanical wristwatch for $800K.

That CNN says it keeps "perfect" time is laughable, but I'll give them that 5 ppm is certainly a high standard for a purely mechanical movement.

But it got me thinking... I've made all the crazy clocks I can think of... but just how accurate could a lavet stepper clock be?

Well, the going rate on eBay for a rubidium standard with 10 MHz output is around $180 or so. A simple firmware tweak should give us the same 10 Hz interrupt source: 10 MHz with a prescale of 16 is 625 kHz. 625 kHz divided by 1024 is 61 5/128, so 5 cycles of 62 and 123 cycles of 61 would be correct.

The result would be a lavet stepper clock that ticked with an accuracy of better than one part per billion. It would be no more than a tenth of a second off per century.

Of course, it wouldn't be synchronized to anything - it would depend on the user to actually point the hands to the right spot. But as long as it had power, you could count on it being a whole lot more accurate than a wristwatch 3.5 orders of magnitude more expensive.

You could do the same thing with GPS much cheaper, of course. You wouldn't even need a microcontroller. GPS modules have synchronized PPS outputs. You could use a flip-flop and two AND gates to turn the PPS output into alternating positive pulses on the two coil wires. If the PPS pulse isn't long enough, then you might need to add a pulse stretcher, but even then a microcontroller is still overkill.

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

Crazy Clock store on Tindie

This page is the permanent home for the Crazy Clock user's guide. It will be updated whenever changes are made. The hardware history:

  • v0.1 - Prototype
  • v0.2 - Changed crystal to HC-49 through-hole footprint and reduced size
  • v0.3 - Slight size reduction
  • v0.4 - Slight size reduction - downgraded over-spec'd parts.
  • v0.5 - Trade out ceramic for tantalum caps in boost section. Dramatic size reduction.
  • v0.6 - Trade out flyback diodes for a single diode array - use same array (wasting one side) for boost section - reducing BOM.
  • v0.7 - Change to a SMD 32.768 kHz crystal.
  • v0.8.x - v0.9.x - All versions the same, just reorganized for smaller sizes.
  • v1.0 & Q80 v1.0 - Same as before, but Q80 variant shaped to be drop-in replacement for Quartex movements.
  • Q80 v1.1 - Move some components for relief, add solder jumper to disconnect coil for programming (if needed).
  • v1.1 & Q80 v1.2.1 - Change crystal to 1206 footprint and add loading capacitors.
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 Xacto 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, again 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.

If you're buying a clock movement to modify with the Crazy Clock, the recommended model is the Quartex Q-80. It turns out, at least at the present time, these are the movements being used by Zazzle for their clocks. The Crazy Clock fits best as shown in this picture:



The crazy clock will run for around 12 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 ticks, actual operation 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 30 seconds per month (±10 ppm), so long as the clock is kept near room temperature (around 25 °C, or 76 °F). When exposed to extreme temperature swings, you can expect the accuracy to suffer.

If you change your mind, you can re-flash the firmware. You may need to disconnect (one lead of) the stepper coil from the clock terminal before you do so, however, as the stepper pins are also used for programming. The stepper coil is a low impedance load, and that might interfere with the programmer's ability to properly drive the pins. To do this with the Q80 board, you can cut the trace between the two pads of the solder jumper near the bottom right side of the board. Once programming is complete, use a blob of solder to short the two pads together again. 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 AVR gcc and binutils toolchain. Because the controller's system clock runs at approximately 32 kHz, the SPI clock for the programmer must be at least 6 times slower. This means adding either the -i or the -B option (depending on your programmer) to AVRDUDE with a value of 250. If your programmer does not support slowing the SPI clock or if it supports doing so in some other manner, you'll need to make whatever arrangements are required.

If you want to build your own Crazy Clock controller from scratch, you'll need to fuse your ATTiny before programming it. The correct fuse settings are low:0xE6, high:0xD7 and extended:0xFF. If you bought a completed crazy clock board, its fuses will have been correctly set, and changing them is not recommended. An ATTiny45 has sufficient flash memory for any of the firmware loads, and an ATTiny25 has enough for all of them except the "Crazy clock." You can build a crazy clock equivalent on a breadboard or some other equivalent prototyping system. If you do, you will either need to use a SOT-23-5 breakout board for the NCP1402, a ready-made boost converter breakout, or just dispense with the boost converter and use some other power supply. Two AA batteries in series would work fine, as would a CR2032 (but it would only last around a month).

Firmware Operating Notes

The Crazy, Early and Warpy firmware, by their nature, drift measurably from the correct time, and the controller cannot know where the actual hands of the clock are pointing at any given time or when they are moved by the set knob. For this reason, if you wish to set the clock, you should momentarily disconnect the battery to reset the controller. This will zero any drift. For the Warpy firmware, the clock will begin the fast-running 12 hour period immediately.

The first four bytes of EEPROM on the controller are the seed for the pseudo-random number generator. Bytes 5 and 6 are active if you enable the SW_TRIM option of the firmware. The values are a little-endian, two's compliment trim value in tenths of a part-per-million. Positive values slow the clock down and negative values speed it up. To obtain the calibration value, you can either observe the clock's behavior for an extended period (although with some novelty firmware this can be impossible), or you can load the special calibration firmware image. This image will output a 16.384 kHz (nominal) square wave on one of the coil pins. You can obtain the calibration value by measuring the actual frequency with a frequency counter and determining the offset from the nominal value.

Testing & Troubleshooting

Testing the controller is quite simple. Attach a two-lead, bi-color LED, such as this one, to the "clock" terminal. In fact, the leads on a 5mm LED are spaced perfectly to fit right in. For testing, don't solder the leads, just stick them in and bend them apart a little to make a temporary connection. Similarly, connect a single AA battery, or some other power source (maximum 3 volts) to the BATT connector. Once powered, you should see the LED blink red and green with whatever pattern is appropriate for the firmware loaded.

If you don't see the LED blink, use a voltmeter and check for 3.3 volts between pins 4 and 8 of the ATtiny, or on the top and bottom of the output filter caps (the two that are next to each other to the right of the battery connector). If you see power, then the problem is likely with the microcontroller (to the right of the crystal). If not, then the problem is with the switching supply (to the left of the crystal).

For problems with the power supply, check for any components that are warm or hot to the touch, or for excessive current draw from the battery. In operation, the crazy clock should draw - on average - less than 100 µA. If it's drawing more than half a milliamp, something is likely shorting out. Also, check for any components that appear discolored or misshapen - a sure sign that the magic black smoke has escaped.

For problems with the microcontroller, check for pulses on pins 5 and 6. If you see them there, but not on the LED, then check the two series resistors and diodes for opens or shorts. If you don't see pulses coming from the microcontroller, check to make sure pin 1 (RESET) is high and use a high impedance oscilloscope probe to check for 32.768 kHz oscillations on pins 2 and 3. If you see them, then if you can, try to re-flash the firmware. If it won't accept new firmware but all of the other tests pass, then the controller itself is likely bad. When attempting to program the controller, don't forget that the SPI clock must be no faster than 4 kHz.

For most clock movements, the pulses of their original controllers are around 30-35 ms long, with an amplitude of ±1.5 volts. The default configuration of the crazy clock firmware uses 35 ms for its pulse length. If your movement is significantly different, this may not work properly. If you have an oscilloscope, you can power the original movement and observe its pulses. If your movement has a second hand that moves smoothly rather than jumps from one second to the next, then it's possible that the controller is "ticking" at 8 Hz (which simulates smooth movement). The default crazy clock firmware is incompatible with these movements, but the hardware could still be used (with different firmware) to alter how these clocks function.

Theory of operation

The battery is connected to a boost converter that will increase the voltage to a regulated 3.0 or 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 ATTiny45 with a 32.768 kHz crystal. Timer 0 is set up for a prescale of 64, for a counting rate of 512 Hz. The firmware will use a special fractional counting method to divide that by 51.2, resulting in timer interrupts at 10 Hz. The SW_TRIM option further "bumps" the timer one count one direction or the other periodically depending on the trim factor. 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.

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. Most lavet stepper coils are a little more than 200 ohms, so 200 ohms added series resistance drops the voltage roughly in half.

Although the Crazy Clock is a digital device, it falls under the FCC part 15.103(h) exemption because it's battery powered and both the boost converter and microcontroller run slower than 1.7 MHz.

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 = 0xfe; // 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.

Monday, August 11, 2014

More fussing about with the crazy clock design

I don't usually breadboard things - I usually just either try to simulate them or just design carefully and order prototype boards. And I did that with the crazy clock too - a prototype board is on its way - but while waiting for it, I did grab a PDIP Tiny85 that I had handy and started experimenting with firmware designs (using two LEDs instead of a lavet stepper). That's how I came up with the firmware that I have now.

But I digress.

One thing I did between then and now was order a new pogo ISP adapter from Tindie. This let me bury the ISP header under the Tiny85, something I wasn't able to do with the traditional 2x3 DIP footprint. That let me dramatically shrink the board from what I had before. And the hope is that the board will be able to be buried inside of the case of the clockwork, so size is quite important.

Unfortunately, the choice of crystal is turning into a big sticking point for the design.

There are a bunch of tensions at work: I usually try to pick the 3.2x2.5 mm 4 SMD pad crystals. They're quite compact and placing them alongside their 22 pF caps has been the usual pattern thus far. And size is, as I said, definitely a factor. But so is accuracy. 10 ppm is just under a second per day, which is sort of at the outer limit of what's acceptable for a clock. And then there's the fact that we want to use the crystal as an interrupt timer for the sketch, which means that we need to work a division by 1024 into the math and still come out with well-timed interrupts. That means our crystal choices are even multiples of 1.024 MHz - which severely limits the choices. The small SMD footprint comes in a 16.384 MHz crystal, but even with a CPU clock pre-scaler, it's looking like power consumption is directly proportional to frequency. So lower frequency crystals are preferred.

In the end, it looks like I'm going to have to go with an HC-49 through-hole footprint. DigiKey does have an 8.192 MHz 10 ppm crystal for 49 cents, but it does force the board to be wider. It's now 1.25" x .55" thanks to the almost giant looking space in the middle reserved for the crystal. But that's half the frequency of a 16.384 one, so the power consumption might still meet my target of less than 500 µA while idling, and with a CPU prescale of 16, that's a CPU clock of 512 kHz. Then with a timer0 prescale of 1024, that's a counting rate of 500 Hz, so a CTC value of 50 yields an interrupt source of 10 Hz - perfect.

Sunday, August 10, 2014

An even better crazy clock

I don't actually have hardware for the crazy clock yet, but I've been simulating it on the bench with a PDIP ATTiny85 and LEDs.

My original inspiration was this clock on Tindie. The seller includes a video showing the clock in action. It's certainly a crazy clock. But I'm not sure the psychology is exactly right. The original clock of Lord Vetinari was designed to subtly play with the mind of the observer. I think there's a better way.

I think to really achieve the goal, the clock should just be quite a bit more regular. After all, subtlety is the goal.

What I've come up with is the notion of periods of time when the clock is ticking double-time and periods of time when it's ticking half-time. As long as the total amount of double-time ticking is exactly matched by periods of half-time ticking, the accuracy of the clock will be unchanged. It's also a goal to insure that the casual observer sees nothing particularly untoward. He might on some unconscious level feel like time is rushing or crawling. But the accuracy of the clock, of course, must be unaffected.

What I came up with is the notion of an "instruction list." The list is periodically constructed and filled with pairs of instruction codes representing a period of half-time, double-time or normal-time. Each pair is either two normal-time instructions or a half-time/double-time pair. Once filled, the instruction list is shuffled. Constructing the list this way will result in apparently random ticking, but at the end of each list, the actual number of ticks will be correct.

Each instruction will be followed for a random - but even - number of seconds (it must be even so that there are no fencepost errors when ticking at half-time). Picking a moderate length of time (10-20 seconds or so) will make the clock appear to be more normal at first glance. But, of course, for the clock to remain accurate, each instruction must be followed for the same amount of time for a single list of instructions.

The hardware has a 16.384 MHz crystal, but the pre-scaler is set to 32, yielding a CPU clock of 512 kHz (if you set the clock slower than that, then uploading firmware becomes problematic - apparently the prescaler is not cleared before programming starts, which has got to be a bug). Timer 0 is configured with the 1024 pre-scaling setting, so it will count at 500 Hz. Setting it up for CTC mode and setting the counter compare register to 50 will result in an interrupt source of 10 Hz. The firmware will use SLEEP_MODE_IDLE and operate by simply entering sleep_mode() regularly to mark time.

In principle, the CPU should spend most of its time in IDLE mode, with a 512 kHz system clock and a 3.3 volt Vcc. According to the datasheet, that should result in a power consumption of only 100 µA. If you assume that the ticking of the clock consumes 10 mA for 30 ms, 3600 times per hour, you wind up with a single AA battery lasting around 90 days. Certainly not as long as a straight-up clock would last, but 90 days isn't at all unreasonable. As a side-effect, however, the boost converter will allow the system to run all the way down to a battery voltage of 0.7 volts, by which point the battery will be well and truly dead.

The firmware is up on Github.

Thursday, August 7, 2014

USB µISP User Guide

USB µISP store on Tindie

This post is going to be the permanent home for user information for the USB µISP. The version history:

  • 0.1: Initial prototype
  • 0.2: Unreleased version - contained an error
  • 0.3: Changed the Tiny2313 power source to 3.3 volts. Removed USB level shifting resistor/zener combination. Added diode+pullup level shifting to Tiny2313 inputs. This version should be able to program target-powered systems down to 1.8 volts (in theory).
  • 0.4: Remove 10 µF tantalum cap. Replace input and output bypass caps on LDO with 10µF and 22µF respectively. Hopefully this will reduce the impact of voltage transients if/when the target is hot-plugged. Change USB- pull-up resistor to be constant rather than logic-gated.
  • 0.5: Add a current limiting switch to the target power circuitry. Should make it safe to hot-plug the target once and for all.
  • 0.5.1: Change the USB- pull-up resistor back to being logic-gated.
  • 1.1: Change to QFN-20 controller and SSOP buffer chips.
  • 1.1.1: Minor silkscreen improvements.
  • 1.2: Change to TSSOP buffer chip.
  • 1.3: Replace voltage selection header with a switch.
  • 1.4: Add a recovery clock output.
  • 1.5.1: Add termination resistors on USB data lines and logic outputs.

The USB µISP is a clone of both the AdaFruit USB Tiny programmer and the SparkFun Pocket AVR programmer. It adds a 3.3 volt regulator which allows target power to be switched between 3.3 volts, 5 volts, or no target power (meaning that the target is self-powered during programming). In all cases, a bus buffer level-shifts all programming signals relative to whatever the target's voltage is.

There is three position switch (or for older versions a three pin SIP header with a jumper) on the top edge of the USB µISP next to the target connector. It is used to select target power. If you place it in the left position (again, with the USB connector on the left), then the target will be supplied 3.3 volt power. If you place the switch in the right position, then it will be supplied 5 volts. If you place the switch in the center position, then no power will be supplied to the target, and it will need to be self-powered.

For versions 1.4 and beyond, there is a single pin in the bottom center which supplies a 500 kHz square wave during programming (it will be in a high impedance state at other times). This can be be used to supply a recovery clock to targets incorrectly fused for an external crystal. The clock's high voltage is the target's Vcc voltage, and low is ground. If your target is incorrectly fused, then connect a wire from this pin to one or the other XTAL pin on the target and try again, adding a -B 250 to the avrdude command line. This results in an SPI clock speed of around 4 kHz. The default value of the -B argument to avrdude doesn't always give the controller enough time to respond. Use avrdude to reset the fuses back to the factory default and then remove the recovery clock wire and try again. Depending on the state of the fuses, it's conceivable that the recovery clock still may not work. If your sketch changes the system clock prescaler, then one trick is to connect the RESET pin temporarily to ground before applying power (or connecting the programmer) to prevent the code from running. If you have disabled RESET, then there is no alternative to HV programming to recover.

When supplying target power, the target can draw up to 200 mA at 3.3 volts or 5 volts. If your target draws more than that during programming, it must be self-powered.

There are two LEDs near the USB connector. The bottom (green) one is labeled "CONN" and indicates that the programmer has been recognized by the host computer. It should always be on whenever the programmer is connected, however it is normal on some systems for the light to remain off until it's first used.

The top LED (red) is labeled "PROG" and indicates that the programmer is currently in use and programming the target. This light should be on whenever avrdude is working, and should shut off when the programming job is finished.

In general, to use the USB µISP, you should first insure that the voltage selection switch (or jumper) is set to the correct position for supplying power (or not) to your target. Next, connect a 2x3 DIP cable between the USB µISP and the target system, insuring that you connect pin 1 on the cable to pin 1 on the plug on both ends (pin 1 on the USB µISP is towards the edge of the board). Lastly, connect the USB cable between the host and the USB µISP. You should see the CONN led light up. Use avrdude as intended and you should see the PROG led light and avrdude should indicate it's working. Starting with version 0.5 of the board, you may connect and disconnect the target while the USB cable is plugged in if you wish.

For avrdude, you should supply the "usbtiny" argument to -c. For the Arduino IDE, choose "USBTiny" from the Programmer menu (under Tools).

If you don't see the CONN light when you connect the USB µISP, check your USB cable to make sure it's connected properly. If it still doesn't light, check for +5 volts on the right-most pin of the 3 pin voltage select header. If you don't see that, then check for +5 volts on both ends of the polyfuse (it is in the top left corner of the board near the USB connector). If you only see +5 volts on one side, then that fuse has blown. It will self-reset, but may take some time (potentially days). If you do see +5 volts all the way to the power select header, check the opposite side for 3.3 volts. If you don't see it, then the LDO has failed and must be replaced. If the power is good, then try plugging the USB µISP into another host.

If the CONN light lights up but avrdude complains that it can't find the target, check the target power switch to insure target power is as you expect it to be. Next, check the ISP cable to make sure you've plugged it in the correct orientation on both ends. Next, make sure you've identified the target to avrdude properly (the -p argument). If it still doesn't work, then it's likely your target has problems.

The most likely target problem is the SPI clock speed. In order to successfully program your device, it's system clock must be at least 4 times (and preferably 8 times) higher than the SPI clock speed. This is set with the -B argument to avrdude. The argument is the number of microseconds (floating point) added to the cycle period (in other words, 1000 divided by the value is the clock frequency in kHz). The default for the USBTiny is 10, which results in a ~100 kHz clock. If your target isn't running at at least 400 kHz, this may be too fast. As noted above, if you write code that alters the prescaler setting, that change will persist across RESET, which means that it will also impact programming. This can bite you if you change the fuse settings or replace your crystal (or both), but don't clear out the flash first. As a workaround, you can remove power, and jumper the RESET pin to ground. This will prevent the code from running, allowing the programming to occur at whatever system clock speed the fuses denote.

Of course, if all else fails, there is always HV programming, but that requires a different programmer.

Schematic

Acknowledgements

I'd like to acknowledge Dick Streefland's work on the original USB TinyISP and the two derivatives 
of it - the AdaFruit USBTiny and the SparkFun Pocket AVR programmer - that directly led to the development of the µISP.

Please do not use the Adafruit USB VID/PID without written permission from Adafruit Industries, LLC and Limor "Ladyada" Fried (support@adafruit.com). Permission is granted for 8pino.cc, Geppetto Electronics, littlewire, Ihsan Kehribar and Seeed Studio and Sparkfun by Adafruit Industries, LLC to use the Adafruit USB VID/PID for approved products. The USB µISP is one such approved product.

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);
}

Sunday, August 3, 2014

DIY Pandora alarm clock

A very long time ago, I was part of a community that reverse-engineered the serial control protocol for the XMPCR - a USB controlled XM radio. I wrote Mac software for it and wound up using it as an alarm clock. I used a cron job and woke up to Squizz (later Octane) every weekday morning.

But then Pandora came along. XM was just too expensive by comparison, so I've been a Pandora One listener for a while. I switched from using a laptop to a Chumby so that I could move the laptop out of the bedroom. And that was fine, but then Chunby fell on hard times and I moved on. My current alarm clock is a box from Grace Audio. And it works ok, but I've gotten into the Raspberry Pi of late, which makes me think maybe I could make my own equivalent.

What got me thinking about this was an item on last week's show-n-tell. A guy showed a LCD screen, Internet connected Arduino alarm clock. I think Pandora would be a bit much to ask of an Arduino, but it should be no problem for a Pi.  

Pithos is a Linux Pandora Radio client. I haven't yet tried it, but it likely would need a different UI in any event. My thought is that a B+ Pi with a touch screen would be a good way to start.

I'll have to think some more about this...

Friday, August 1, 2014

MicroBoost success

My initial prototype boards for a MintyBoost SMD clone came back. They work up to 500 mA. I tried to run one at 1A, but the inductor failed spectacularly. I do think I'm going to try and upgrade the next version to 1A if I can. I've found a beefier inductor and I already have some good Schottky diodes that are a step up from the MBRA140. I've also changed the shape a little so it has a better shot of fitting in the "gum" size AdaFruit tins for a 2 AA variant (that would only really be expected to work at 500 mA though).

But I dunno if I want to bother. About the only argument I could make in favor of adding this to my Tindie store is that I think my design could be made much cheaper than any of the other prices for this I see elsewhere - probably $10 for a complete board with your choice of either 500 mA or 1000 mA "Apple charging" resistors (you have to use resistor dividers to tell an iDevice how much current is available, and you'd want to set up a 2 AA charger for 500 mA and a 3 AA charger for 1000).

But would anyone want one?

AC power frequency monitoring experiment

Here in North America, AC power is delivered at 60 Hz. Back in the day, electric clocks were designed with synchronous motors whose rotation was directly linked to this frequency. Later, electronic clocks were designed to actually use the AC line frequency as the timebase. This worked because the standards for electricity delivery called for long-term accuracy.

How can this be? The line frequency is subject to reduction when highly inductive loads are imposed on the grid. Well, the standard says that the accuracy specification for the frequency is only a long term value. You can count on seeing 5,184,000 cycles in a day on average. If demand creates a frequency sag, the utility is supposed to make up for that later with a matching period of higher frequency.

Well, if that sort of thing is going on, it ought to be something that can be measured.

The AdaFruit Ultimate GPS breakout board is a good way to get an independent reference. It's PPS output is 100 ms positive-going pulses once every second, with nano-second levels of precision and accuracy.

We can take that PPS output and apply it directly to the INT0 pin of an Arduino Uno. With a RISING interrupt set on that pin, we'll be able to precisely gather statistics on second boundaries.

For the AC input, the path of least resistance is to buy a small AC-AC "wall wart." 9 volts would be fine, but anything under around 20 volts would work (the limiting factor is the -0.3-36 volt absolute maximum input range of an LM393). The shield of the wall wart will be tied to ground and the center pin run through a simple signal diode with a 20k pull-down on the "far" end and into the positive side of an LM393. The negative side will have a voltage divider with, oh, say, 2.5 volts on it. The result of that will be a square wave whose frequency equals the frequency of the incoming AC. Now, the duty cycle will be a mess, and there's no particular assurance that the comparator output will be synchronized to the line frequency, but none of that matters. We really just want to count the positive-going excursions, just like we're counting the rising edges of the GPS PPS output. The output of the comparator (with the pinMode set to INPUT_PULLUP) will go into INT1 and - again - a RISING interrupt will be set to count those pulses.

Most of the time, when the PPS interrupt is triggered, I expect the frequency interrupt count to be 60. When it is, that doesn't need to be reported. But occasionally, I expect it to be 59 or 61. Perhaps even occasionally 58 or 62. Those are noteworthy.

The hypothesis of the experiment is that over a long enough period of time, the sum of all of the offsets from 60 will be zero.

So the sketch:

setup() will set up the interrupt service routines. The PPS interrupt will gather the current AC interrupt count into a global reporting variable, clear the active counter and set a mark. The AC interrupt will increment the interrupt count only.

loop() will simply wait for the PPS interrupt flag and check to see if the delta of the count from 60 is zero. If it is, then it will ignore that interval and wait for the next one. If it is anything else, then that will be printed on the serial output.

I'll probably wire the serial output to my raspberry pi via an FTDI cable and set a little daemon up to capture and report all of the offset events. I can then make nice graphs and stuff.

This'd be a heck of a science fair project... Hmm.