Monday, December 29, 2014

OpenEVSE II - progress at last

After letting the prototype boards sit on my bench for almost six months, I finally got around to building them.

I've got to redo the voltmeter portion of the HV boards, so there will be a 0.3 board, but I think the 0.2 logic/display board is a keeper.

Here are some docs to peruse:


The relay board variant is designed to be used at both L1 and L2, but the relays are limited to 24A continuous (30A circuit breakers / fuses). The contactor board variant can be used with any line-powered contactor and the design imposes no current limit constraints beyond that of the contactor, AC and J1772 cables. But the contactor coil will likely only be usable for 208/240 volt power (you could get an 120V coil contactor, but for L1 you might as well use the relay variant).

Saturday, December 20, 2014

Contactor Adapter users guide

This post is the permanent home for the instructions for the Contactor Adapter.

Version history:


  • 1.4: Increased creepage distances for improved safety and isolation.

Contactors are very similar to relays. Classically, the term is used to describe relays that switch higher powered loads on and off, and typically have AC line voltage powered coils, while relays tend to be smaller and have low voltage DC coils.

The initial project that drove the design of the contactor adapter was OpenEVSE. The OpenEVSE and Hydra boards had switched 12 volt outputs designed to open and close relays to turn the power to the car on and off. 30A DSPT relays were not hard to come by, but they came with QD terminals. QD crimp terminals for 10 gauge wires can be had, but in heavy usage they were not reliable.

Switching to contactors resulted in a much more reliable design for the high-current paths, but led to the need for the contactor adapter.

To make use of the adapter, first pick a contactor with a coil whose voltage matches the voltage of the load that you're going to switch. The contactor adapter is rated for 240 VAC RMS maximum (it can be used at 120 VAC as well). Insure that your contactor coil draws no more than 100 mA (most won't) not counting initial surge currents.

The contactor adapter's high voltage terminals are a switch. Wire the contactor so that one coil terminal is fed directly from one of the line inputs. Wire the other contactor coil terminal to one of the contactor adapter's high voltage terminals. Wire the other contactor adapter terminal to the other line current source. If you're using hot-neutral wiring, then you should place the contactor adapter in the hot line rather than the neutral line. If you're using hot-hot wiring, then it does not matter which hot line you use.

The input side of the contactor adapter is effectively an LED. The contactor adapter is supplied with a 330 ohm series resistor, which means that the ideal switching voltage is 12 volts. The contactor adapter will draw approximately 30 mA. If you wish, you can replace the series resistor with a 150 ohm one, in which case the contactor adapter can be driven directly with a (5 volt) output pin from a microcontroller (assuming that that one pin can drive 30 mA).

Unlike relay coils, the contactor adapter is polarized. You must connect the positive terminal to the voltage source and the other terminal to ground. For OpenEVSE boards, the common center pin of the relay terminal is positive, the individual relay pins are ground.




Note that most of the board has line voltage present when it's connected - and this includes the bottom of the board. Mount the board securely with appropriate mounting hardware, including standoffs to keep the bottom of the board a minimum of 1/4" away from anything else.

Schematic:


Wednesday, December 10, 2014

On hardware versioning

I don't know if this is a particularly interesting topic for a blog post, but I sort of had a realization last night about how best to manage hardware version numbering.

What it comes down to is the nature of the change that requires crossing a particular boundary. I've identified three boundaries:


  1. A major design change - wholesale changing of chips, new hardware features, etc.
  2. A change that impact the "cream" layer - requiring a new solder paste stencil and/or PnP programming.
  3. A change in signal routing or silkscreen - requiring new PCBs.
  4. Any other change - typically just parts substitution, stuff/no-stuff or solder jumpers.
Going forward, this is how I'm going to version hardware. I'm going to use the old software standard of n.m.o formatted version numbers, but other folks prefer Axy style, and that's fine too. But I've discovered that there is value to characterizing which changes require a new stencil, and this scheme means I don't have to try and remember that 0.3 could still use the 0.2 stencil.

Sunday, November 9, 2014

AP2331 FTW

I've been using and selling my USBTiny clone for a little while now, and it's been a great little device for the most part. But there's one little detail that's bugged me just a tiny bit: It's not hot-plug safe. In general, you need to attach the ISP header first, then plug the USB cable in. If you try and hot-plug it,  particularly when it's jumpered for 3.3 volts, you risk glitching the Vcc supply of the Tiny2313. This can cause the USB to reenumerate, at best, but most of the time it just causes the 2313 to lock up. Solving the hot-plug problem is particularly meaningful when you're using pogo pin programming, as cycling the USB connection while holding the pogo pins perfectly in place is difficult at best. I've tried to address this in the past by adding additional capacitance before and after the 3.3 volt LDO, but that didn't really help.

I happened to think about the Raspberry Pi. On the model B, I was able to cause a reset by removing the WiFi USB dongle. But for the B+, they added additional circuitry to mitigate this. What was it? The AP2331. The device is simplicity itself. It's an SO23-3 with pins for in, out and ground. It was designed for USB power applications, but it's usable at 3.3 volts as well, which makes it ideal for my purposes.

I tested one using pin clips to attach it to my current revision of board, making it the bridge between the 3.3 volt and target power pins of the jumper block, and pulling ground from the controller. Without it in place, I could cause glitches on the controller fairly consistently with a pogo adapter and a Crazy Clock board. But with the device in place? Nothing. It just worked.

So I'll be adding one to the 0.5 version of the µISP. That'll raise the price of it by a dollar, but that won't go into effect until the current inventory of 0.4 boards is cleared out.

Sunday, October 26, 2014

usbtinyisp source code update for modern AVR GCC

For those besides me who have downloaded the source code to the USB Tiny from AdaFruit, you'll note that on the download page it says you must use gcc-3.4.6 to build it. That's an antique.

I started down the road of patching the code so that it can be compiled by a modern AVR GCC and libc, but eventually discovered that someone had already done it.

I then went on to find the original home of the code. He has a 1.7 version of the code, but the pin assignments are different. The following patch makes it work with the USB µISP up through the current version (0.4) (it should also work with the original AdaFruit USBTiny and the SparkFun pocket AVR programmer):

EDIT: Turns out the patch was unnecessary... I was trying to build from the 'spi' directory, but the correct place is the 'usbtinyisp' directory. That has the correct pin assignments and requires no modifications. Just 'make' and reflash. Joy!

Thursday, October 16, 2014

Learning more and more about AVR libc

Since I converted the crazy clock to straight AVR GCC, I've been learning more and more about the AVR libc.

Before, I had written my own delay_ms() method for the ticking, but in looking into the library-supplied _delay_ms(), I discovered enough that I've switched entirely over to using it.

In particular, as long as you call _delay_ms() with a value that's constant at compile-time, the actual assembler code that will be generated will be nothing more than the assembler equivalent of "for(i = 0; i < magic_value; i++) ;" The compiler will select the "magic_value" based on the F_CPU macro (which is the frequency of the clock in Hz) and the actual number of clock cycles that the compiler knows each instruction will require. In my case, the code actually shrank by a few bytes compared to my old code which watched the timer0 count (the old code was also problematic in that it would lock up if the counter overflowed during a delay). This is all despite the fact that the ostensible argument to _delay_ms() is a double. But as long as the value is a compile-time constant, the compiler will optimize away all of the floating point requirements and will figure out that it needs to delay a particular number of cycles, and will generate assembly code to do exactly that. Brilliant!

And if you just need to waste a certain number of cycles, then __builtin_avr_delay_cycles() will generate exactly the correct code. I believe this might be useful to simplify some of the bit-bang USB code in the usbtinyisp. That will need careful consideration...

Sunday, October 12, 2014

Initial crazy clock programming/test jig

I still can't bring myself to pull the trigger on a panel of crazy clocks. But in the meantime, I have decided to go ahead with a jig for at least single boards.


The concept is that the two ISP footprints are connected together, the two battery footprints are connected together and the clock footprint is connected to two inverse parallel LEDs. The battery, clock and ISP footprints that match up with the actual board will be populated with pogo pins. The extra battery jack will connect to a right-angle 1x2 header and the extra ISP footprint will connect to a right-angle 2x3 header. That will form the bottom board of the jig. The top board will have the two SMD LEDs mounted. The pogo pins will project out of the top, and there will be some rubber feet for stability on the bottom.

To use it, you connect an AVR programmer configured for a self-powered target to the 2x3 header and a single AA battery to the battery connector. You then hold a freshly manufactured board on top of the pins and press down (for hands-free operation, you could use a few ounces of weight - say a paperweight wrapped in electrical tape). You then use your other hand and press return on the Raspberry Pi that has the AVRDUDE operations scripted. If the programming steps work (and if the programmer is configured to not deliver target power), then that confirms that the boost converter works. At the end of programming, the two LEDs should start blinking in the correct sequence for the firmware that was loaded. That confirms that the firmware works and that the series resistors and flyback diodes aren't wired incorrectly.

Monday, October 6, 2014

DIY AVR ISP Pogo adapter

I've been using the SparkFun one for a while, but it's not absolute nirvana. In particular, I don't have any use for the molex connection or the JST power jack, and having the host jack be on the top makes it somewhat more awkward to hold.

So I came up with what I think is a better design.

You start with a very simple board with two 6 pin AVR ISP footprints. Be sure that the holes are 46 mils. Connect each pin on one to the matching pin on the other. Put two #4 holes on either side, insuring that you've got enough space so that the screw head won't abrade any of the traces.

Here's the OSH Park shared project for my design.

To make one adapter, you need two of these boards. You also need two 1/2" #4 bolts, two #4 nuts and two #4 1/4" standoffs. You'll also need 6 pogo pins and a 2x3 .1" right angle header.

Start by picking one of the boards to be the bottom board. Solder the right angle header into the ISP footprints that is not the one next to the writing that says "Pogo pin side." This is the side with the pins named.

Next, use 2 1/2" #4 bolts and nuts and a 1/4" #4 standoff to attach the two boards together, placing the one with the right-angle header on the bottom. It is critical to insure that the two boards are oriented the same way - both TOP sides up, and both facing the same direction. If you get this wrong, the adapter will be miswired.

Place some scotch tape on the top of the top board, covering all of the holes in the ISP footprint that is marked "Pogo pin side."

Flip the boards over and carefully insert the pogo pins into the holes, with the silverish, pointy ends up. Be very careful with this, as the pins are easy to bend (which will ruin them), and are a very, very snug fit (they're 40 mils wide, and the holes are ostensibly 46 mils wide). Make sure the ends of the pins come through the holes in the top board and rest against the tape. When all the pins are in place, the tops of the pins must be level.

Take a moment to check that the pins are square, straight and the tops are level. If the pins are racked at all, twist the boards relative to each other, loosening the hardware slightly if necessary.

When the pins are placed properly, solder them to the bottom board. Once that's done, remove the scotch tape from the top board and solder the tops of the pins to the top board.

And you're done!

Attach your programmer to the header, being sure to put pin 1 on the pin 1 end (you can look at the markings on the top board to figure that out). Orient the pogo pins so that the pin 1 marking on the board match the target. Press down slightly so that the springs put a little tension on the target, but not so much that the springs bottom out. Hold it there and do whatever needs doing.




Saturday, October 4, 2014

Recovering pooched ATTiny chips

I never thought I would resort to AVR HV programming to recover chips. I probably still am not going to do it for parts actually installed in-circuit. But I had one DIP Attiny85 handy and wanted to get it going again, and no combination of SPI clocking and various other tricks got it to answer.

So I decided to set down the road to see if it were reasonable to do just this once.

I found this page, which was the most helpful. It turns out, that if you just want to do a quick-n-dirty one-off, you don't need to go to quite as much trouble.

Here's what I did:

I loaded the sketch into my Uno. D9 goes to pin 2 of the target. D10 to pin 5, D11 to pin 6, D12 to pin 7, +5 to pin 8, GND to pin 4, and then I took my bench power supply and set it for 12 volts and applied that to pin 1 (with its ground also going to pin 4).

I opened the Arduino serial monitor, entered a character in the input line and it promptly reset the fuses to the factory default. Mischief managed.

Wednesday, October 1, 2014

Microcontroller panel programming jig for crazy clock

I'm considering making a whole pile of crazy clock retrofit boards.

Step 1 of that is panelizing the boards. This is a bit of a tricky operation in Eagle, as it involves breaking the normal synchronizing connection between the schematic and the board. You start by making a copy of just the .brd file for your design. Open the copy and modify it by replacing the box around the outside of the board with a series of disconnected lines, leaving a 100 mil section on each side that's not detached. Next, use the group tool to lasso a box around your entire circuit and use the clone tool to copy it, placing the copies in a grid. Once you're done with that, add another outline to the dimension layer to make a frame around your boards. The purpose for the space between the boards and the frame around the outside is twofold - to add structural integrity to the panel as a whole  and to space the boards a bit to aid in pick-n-place operations.


You'll notice that there are 10 holes around the edge of the panel. The purpose for those holes takes us to our next manufacturing step. Well, not quite. The crystal for the crazy clock is a through-hole part. Those have to be installed by hand individually. There's no escaping that, unfortunately. If you don't do it yourself, you've got to pay someone else to do it - it's not a step that can be easily automated.

The crazy clock is a microcontroller based product. Micro controllers come from the factory blank. Before they can do the work for which they're intended, they must be fused and programmed. The crazy clock board has an ISP footprint on the bottom for this purpose. But the job requires connecting a programmer to it long enough for it to talk to the controller and give it its programming.

Since so far the crazy clocks have been programmed to order, but if you're going to get 300 boards picked-and-placed en masse, you're not going to want to break the individual boards out and fuse and program them individually. Instead, you're going to want to make a jig to hit a bunch of them in a single step.

At first, I had a mental image of an ISP squid made of a 6 port USB hub, 6 USB AVR programmers, ISP cables and a pogo adapter. There just had to be a better way. And, indeed, there is. This guy has designed a combination of sketch and java code to make a standalone scripted AVR programmer. Hook it up, push the button and wait until the green LED lights up. Lather, rinse, repeat.

The only downside is that his reference design is based on an ATMega1284P. Since I'm programming ATTinys, I don't need such a huge chip to do the job. I'm going to adapt his code to use an ATMega328P instead.

And this takes us back to those holes. The holes are intended to fit over #4 bolts on the programming jig. Each pair of holes at the top and bottom will be used to align a 6 position programming jig to hit six of the controllers at once. Once the first six are done, you move the jig to the next hole and repeat the operation on those six. And so on.

While I'm at the programming, it'd be a really good opportunity to actually test the boards as well. There are two parts of the board that need testing - the boost converter and the controller and clock interface. The natural way to test the power supply is to have it actually power the whole thing while the programming is taking place. An ATMega master and at ATTiny slave during programming shouldn't require more than a few mA - well within the designed capabilities of the converter. And once the programming is finished, the sketch should start running, and pulses should start coming out of the clock terminals. Detecting those are a simple matter of a pair of LEDs mounted in opposed-polarity parallel. Each crazy clock board will individually power its own programmer. The only common connection between the boards will be the BATT connector supplying 1.5 volts to all 6 from a AA battery, and the GO pin coming from a switch mounted on the corner of the board to initiate the programming process.

OSH Park sells individual boards by the threes. This is ideal for pogo pin jigs, because you want to use two boards held a fixed distance apart to hold the pogo pins straight and parallel. The top board will be fully populated with all of the LEDs and controllers. The bottom board will get no parts other than the pogo pins coming through from the top. The two boards will be held together with 4 1/2" standoffs and 8 1/4" bolts.

Of course, you need to program the ATMega controllers before you can use the jig to program the ATTinys on the panel(s). Each ATMega will need its own ISP. You can't re-use the target connector because it's going to have pogo pins installed in it. Well, that, and the !RESET line isn't actually connected to the !RESET pin of the ATMega, but rather a GPIO pin so that the mega can assert it to force the tiny into the programming state.

So you connect a AA battery to the power input of the jig, then press the jig down on the panel and press the button. You should see the programming LEDs go from red to green, and then each of the pairs of test LEDs will start blinking in time with whatever pattern was loaded.


Friday, September 26, 2014

AVR ISP Pogo adapter

I've been buying and using SparkFun's ISP Pogo adapter, but there are a couple of things about it's design that - at least for me - could be improved.

The basic design - two boards that are rigidly fixed in a precise vertical alignment each supporting the pins - is good. But I don't value the Molex and JST connectors. I'd rather be able to grasp more easily onto the top board without having so much stuff in the way.

Fortunately, designing one isn't hard. Just put two 6 pin AVR ISP footprints on a board and connect each related trace. You use a pair of boards to make one fixture, and since they're both the same, they'll both align perfectly. You use a pair of snap-in board spacers between the two boards to hold the boards together. With the spacers, there will be enough room on the lower board to install a right-angle DIP header, leaving the top of the top board completely open and usable as a grip/pressure surface.

You assemble the adapter and align the pogo pins the same way SparkFun says to do it on theirs. Start  by attaching a 2x3 right angle DIP header to what will become the bottom board, making sure to install it on the TOP of the board, and that it doesn't stick up more than 1/4 inch (so that it won't touch the top board once it's in place). Next, mechanically assemble the two boards together with the two spacers, making sure that the TOP of each faces the same direction and is oriented the same way. Next, temporarily attach a piece of cellophane tape to the top of the top board, then insert the pogo pins through the bottom board and into the holes of the top board so that they rest against the tape. Carefully check the pins to make sure they're straight and level. If the pins are racked, twist the boards so that they're straight, loosening the hardware if necessary. Solder the pins to the bottom board, then remove the tape and solder the pins from the top of the top board. The second footprint on the top board will be left unconnected.

It turns out that SparkFun's drill holes are the same diameter as the Pogo pin itself. They may be counting on their PCB vendor consistently erring on larger holes. I can only hope that OSHPark does the same. A snug fit is ok, but not fitting at all would be bad. We'll see.

I envision bigger things from this design, potentially. Because the top is (nominally) flat, you could replace the spacers with longer screws, attaching the whole adapter to a larger programming jig, possibly for mass programming panels of devices all at once. The only hard part of that is figuring out how to get avrdude to individually address multiple USBTiny programmers simultaneously attached.

Monday, September 22, 2014

Crazy clock power consumption

I've been mostly guessing about the power consumption of the Crazy Clock controller. But today, I validated my guesses.

My Rigol DS1052E doesn't have an integration function. As Dave explained recently on EEVblog, integration is the best way to quantify power consumption when the waveform is complex. If you can graph amperage against time and integrate that, the result is energy consumed against time - mAs/s. It's not exactly analogous, because the mAs/s isn't really a rate. It's the number of mAs consumed in a second's worth of time.

I took the whole kit-n-kaboodle to work today early and performed the integration. The result was that while the controller sleeps, there's around a 1 kHz complex waveform consisting of a sharp rise to 1.25mA or so, then a decay down to 0. My Rigol scope said it was an average of around 220 µA. But is that accurate in terms of energy consumption?

The integration function over one cycle of that complex waveform reported 220 nAs (actually, it was 220 µVs, but with a µCurrent Gold set for the µA/mV scale, so change Volts to Amps and divide by 1000). Since that was over the course of 1 ms of time, it's 220 nAs/.001 sec, or 220 µAs/s - the same as the 220 µA average current reported by my Rigol.

And that makes logical sense as well. The boost converter is turning 1.5 volts from a AA battery into 3.3 volts, and the datasheet says it should be doing so at roughly 80% efficiency. The ATTiny while napping should be consuming around 100 µA @ 3.3 volts when clocked at 500 kHz. In principle, that means that the battery draw should actually be something like 275 µA, so it's probable that either my measurements are a tiny bit off, the controller is a tiny bit more frugal or the boost converter is a tiny bit more efficient. Or all 3. But it's still in very much the correct ballpark.

Saturday, September 20, 2014

Failure is one thing. Not knowing why is another.

For the first time, I'm stymied.

I've made mistakes since I started this making thing. All of them have been learning opportunities. If you've bee following me on twitter, you'll have seen some "Tips du jour" - most of those are lessons that I've learned from figuring out what I did wrong.

Well, now I've got a situation I can't figure out.

I have the same circuit on two different boards. One one board, it works perfectly. On the other, it doesn't work at all.

The circuit in question is a boost converter based around the NCP1450-5 boost controller. Both circuits have the identical schematic. The board layouts differ, but  I've conferred with a colleague at work and he didn't see anything wrong with it either.

The symptom is that with no load, the output is 5 volts. But while circuit A can supply up to an amp of output with less than a tenth of a volt of sag, barely 100 mA of load on circuit B is sufficient for the voltage to sag down to the battery voltage. It's as if the controller "gives up" on trying.

My first thought was that the feedback sampling was being drawn from too close to the output of the regulator as opposed to near the load. But if you do the math, there isn't enough voltage drop on the traces of either design to account for anything.

I then thought that perhaps the output filter cap was too far away from the cathode of the diode. So I added a 68 µF tantalum cap tacked onto the end of the cathode and a short wire to ground. That didn't help.

The board that doesn't work also has a LiPoly battery charger on it, but the exact same circuit on a separate board has been used in concert with the working version of the booster board for a while now, so the mere presence of that circuit doesn't cause any trouble (and why would it anyway?).
The schematic

The board that doesn't work


The board that works.

Monday, September 15, 2014

Pi Power destructive testing report

I took some time this evening and pressed Pi Power to, and beyond, its limits.

First, one thing I discovered is that the failure mode that I observed was that the MOSFET shorts. That causes the input voltage to pass through unmodified to the output voltage, which would likely destroy the Pi. I think a follow-on version of Pi Power will need to add an output over-voltage protection circuit of some sort. That will, however, raise the price.

Second, it looks like I am going to need to de-rate the top end of the voltage range. As the input voltage increases, so does the switching frequency. At 14 volts, the frequency is north of 300 kHz. That's enough that the capacitance of the MOSFET (that is, its maximum switching speed) starts to contribute excessive power dissipation, causing it to heat up. 2 amps at 15 volt input was enough to blow the MOSFET after a few minutes. At 14 volts, it was still hanging on.

I also pressed Pi Power with 9 volts input to see where the current overload protection would trip. When I tried it before, I was using a weaker 12 volt power supply which wasn't able to get that far. I found that the current protection kicks in at around 4.25 amps. The current limit resistor value of 39 kΩ came out of an online TI design tool. I did the math on the datasheet and came up with a value closer to 22 kΩ, and posed a question to StackOverflow about it and never got an answer. But it looks like my calculations were more correct than TI's. The question is whether to change the value in the design to reduce the current limit to be more in line with the limitations of the circuit, or leave it high so that it basically just protects against dead shorts.

Still, in most cases I've personally observed, the current draw of a reasonably loaded Raspberry Pi is closer to 1A than 2. And at that load, with an input voltage of 6-14 volts, Pi Power does just fine.

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.

Tuesday, July 29, 2014

An improvement for the USB µISP

I wanted the USB µISP programmer I designed a couple posts ago to be agile down to 1.8 volt systems, but the problem with that idea is that the voltage "break point" for a 5 volt ATTiny2313 is too high to register a 1.8 volt logic high.

But it struck me... why power the ATTiny with 5 volts? I went to the trouble of adding a 3.3 volt LDO to the thing... Why not have that power the controller as well as the target (if selected)?

If you do that, you can also dispense with the level shifting hardware for the USB pins - you can just connect them directly up! Because of the 74HC125 bus buffer, you can program 5 volt systems just fine, since it will happily level-shift the SPI signals up to 5 volts. When the bus buffer is powered by 1.8 volts, the logic high threshold for a 3.3 volt 2313 is still met, and the reverse is true when the bus buffer is powered by 5 volts.

So the net result is that the v0.2 of the µISP should be able to program AVRs operating at all allowable voltage ranges, and can optionally power either 3.3 or 5 volt targets!


Sunday, July 27, 2014

My take on an AVR ISP programmer

I've been using the SparkFun Pocket AVR for all of the time I've been doing it.

It does well enough for what I need, but it does have a couple of deficiencies that I'd address, if I had my druthers.

Firstly, it comes with a Mini USB plug. It's the only thing in our house that has one of those. Everything else is either full size or micro-B. I'd much prefer either over the now oddball mini B connector.

Secondly, though it comes with a switch to select whether or not to apply target power, there is a leak through the buffer control pull-up resistor that applies power even when target power is disabled. Others on the SparkFun comments for the product have noted this, pointing out that it's not safe to use with 3.3 volt devices. Even if it were, your choice is to either power the target at 5 volts or not power it at all.

Adafruit was the source of the original design. They sell a USB Tiny AVR kit. It didn't have the problem of leaking USB power to the target despite target power being disabled because it simply lacked the pull-up resistor. But that means that if you leave the USB end disconnected that the buffer pin will float, potentially taking the buffer chip out of its high-impedance state when you're not actually programming. Also, like SparkFun's programmer, there's no choice other than 5 volt target power or nothing.

So I sat down to make the best-of-breed USB Tiny ISP. My design is all surface mount, so it's quite small. It has a 6 pin ISP socket rather than a 10 pin, because 6 pin is all I use, and if you must, you can always make a wiring shim to turn 6 into 10. Like the original design, there is a 74HC125 bus buffer chip, and when target power is turned off, it is itself powered from the VCC pin of the ISP plug, so it is guaranteed to feed target-power based logic levels at all times. My addition to the design is a 3.3 volt LDO and a 3 pin .1" header that can be used with a jumper to select whether to provide the target with 3.3 volts, 5 volts or no power at all. I also kept the SparkFun addition of a PTC on the USB power input to protect the host PC. In the SparkFun version, they added a pull-up resistor on the BUFFEN line to insure that when the programmer wasn't actually programming the target that the buffers would be tri-stated. The problem with their design is that nothing prevents 5 volt power from being applied to the target through the pull-up from the CTL line when it is high. A simple 1N4148 diode fixes that problem.

In fact, the SOT-23-5 layout for the LDO can, in principle, take a 1.8 volt LDO as well, should you be designing for that voltage instead of 3.3. Turns out that the problem with a 1.8 volt programmer is that the ATTiny still running at 5 volts has a logic-high threshold of over 2 volts. A 1.8 volt programmer would need similar diode-and-pullup treatment on the "near" side of the bus buffer chip, and I'm not going to bother with that. You could power the ATTiny at 3.3 volts. You'd then have to move the zener-and-protection-resistor trickery from the USB bus pins over to MISO. I might consider looking into that as a next step in the design if 1.8 volt programming is a real demand.



JP1 is the self-programming interface. Since the 2313 is SMD, there's no (good) opportunity to program it out-of-circuit, so there needs to be an ISP for it, and since the buffer chip isn't bi-directional, the target ISP socket can't be used. Since I have a pogo pin ISP adapter I got from SparkFun, I can program the 2313 with that and to save space, bury it on the bottom of the board under the 2313.