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 40 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 one of the ISP footprints.

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 not above the header you installed. That's the side of the adapter that will take the pogo pins.

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 40 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.

The only downside is that it's not so much less expensive than the SparkFun one that I can stock them in the store.


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. My big hope is that if I use a pair of 1/2" #4 threaded spacer between the two boards and a 1/4" #4 bolt on both sides of each to hold the boards on, then there will be enough room on the lower board to permanently attach an IDC 6 pin cable to a 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 2x6 header to what will become the bottom board, making sure to install it on the TOP of the board. Then attach a 2x3 pin IDC cable to that. Next, mechanically assembling the two boards together, making sure that the TOP of each faces the same direction and is oriented the same way. Then you 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. 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 remove the top two screws and screw longer ones in, 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.