Animatronic Yoda 2.0: Eyes, part one

Over the past couple weekends, I’ve managed to spend some time working on my animatronic Yoda head.

A couple years ago, we had a hack day at my previous job, and I built, with one other guy, a talking Yoda head with red or green glowing eyes that served as a build status monitor.  That is, whenever our build (with all our automated tests) was passing, Yoda’s eyes would glow green.  As soon as the build failed, the eyes would change to red, and he would say something.  The jaw would move, and the speaker would play some kind of Yoda related sound effect.  When the build was fixed again, Yoda’s eyes would go back to glowing green, and he would say something positive.  Here’s a little video of him:

Unfortunately, Yoda wasn’t build to stand the tests of time.  We moved offices, and he was damaged during the move, enough that he didn’t function any more.  Considering he was built in only 16 hours, I think he did well.

Fast forward to now.  There were tons of things I would have liked Yoda to be able to do, but that we obviously couldn’t get done in only 16 hours.  So I’ve decided to build a new and improved Yoda, which I’m calling Yoda 2.0.  My goal is to have him done (well, at least somewhat done, there will always be more to add) in time for Vancouver Mini Maker Faire 2012.

I decided that one of the first things to tackle was the thing I expected to be the hardest: the eyes.  I want Yoda 2.0 to be able to look left and right, up and down, as well as near and far, which means independent horizontal control for the two eyes.

I figured I would use two micro servos for each eye, to look left and right, with a common frame for those servos, and a third servo to make him look up and down.  With that plan in mind, I proceeded to construct this:

Original eye frame
Original eye frame

The metal is all from the frame of an old laptop screen, which has since been turned into a digital photo frame.  It’s quite strong.  I broke a few drill bits trying to drill only a couple holes in it.  The idea was that the horizontal frame would rotate along the horizontal axis of the two ping pong balls used as eyes.  To achieve this, on the left and right edges there is an upside-down L bracket coming from the rear horizontal bar, that comes up right beside the eyes.  This bracket has holes in it in like with the horizontal axis of the eyes.  My plan was to mount this to the head on pins of some sort, to allow it to rotate.  The servo in the middle is also in-line with the axis, so by mounting that rigidly in the head, it should allow the eyes to look up and down.

A short aside:

A few weekends ago, I went antiquing with my girlfriend,  and found a metal helmet:

Metal helmet from antique store
Metal helmet from antique store

I took one look at it and thought “Yoda”.  Thankfully, it was only $12, so I bought it, took it home, and went straight to work with my Dremel, ending up with this:

Yoda's new skull
Yoda’s new skull

Excellent! It fits perfectly inside the Yoda mask, and should serve as a perfect frame to attach everything to.

So, back to the eyes.  I decided to use some of the PCL I have kicking around to make a prototype of a way of mounting the eyes to the head.  I decided I better make it adjustable though, because it was very hard to figure out exactly where on the metal skull the eyes should be positioned.  How far down, how far out, etc.  I may have gotten a bit carried away though, because this is what I ended up with:

Adjustable eye mount
Adjustable eye mount

The bit on the left is where the pins should go to hold the eye frame, and allow it to rotate, and the slots on the right should mount on the side of the helmet. So, I got it all mounted, and this is what I ended up with:

Original eye frame mounted on helmet
Original eye frame mounted on helmet

The center servo isn’t yet attached, so I can rotate the eyes by hand to see how it works.  And it worked great.  Until I put the mask on it.  The PCL mounts on the left and right stick out way too far sideways, and to far forward from the eyes, which either leaves them stretching the mask so badly that the PCL mounts are visible through the eye holes, or leaves the eyes sat back so far you can hardly see them.  Well, back to the drawing board.  I decided to call it a night.

Somewhere between calling it a night, and getting back to the workshop the next day, I dreamed up a better idea, and decided to start from scratch, rather than trying to refine the original frame. I decided to put the up-down swivel point between the eyes, instead of on the outside, and mount the servo away from the actual axis, and use a rod of some sort to actuate it. I didn’t have the idea perfectly worked out before I started, I just kind of trusted that I’d be able to work it out somehow.  In the end, it paid off. Here is the new eye frame, from the back:

New eye frame (back view)
New eye frame (back view)

This new one is all made of copper and brass tubing, soldered together.  (I managed to get a couple pounds worth of left-over small copper and brass tubing from a model railroader for $10 a few weeks ago, which just totally paid off.)  The swivel is made from a hollow brass tube, with two slightly smaller diameter brass tubes inserted into it, and bent at a 90 degree angle, then slotted through holes drilled in the square copper bar, and soldered together.  It rotates perfectly, so I went ahead with mounting it in the head.  I did this by making a PCL mount in what I thought might be close to the right shape, and double-sided taping it into the helmet with the mask on it, to test:

Test fitting the new eye frame and mount
Test fitting the new eye frame and mount

It actually seems to fit pretty much perfectly, so I went ahead and drilled some holes to bolt it in solidly.

The next step was to make it look up and down.  I spent quite a while playing with different bits of brass tube (best purchase ever) trying to find a way to actuate it through the range of motion I wanted, from a servo mounted somewhere in the skull.  Eventually, after much trying, I got what I wanted, made a quick PCL mount (I love PCL so much) and came up with this contraption:

Vertical movement eye servo mounted
Vertical movement eye servo mounted

It works pretty well, as this video shows:

As you can see in the video and photo, I added a little bar to the back of the eye frame, and slotted a brass rod from the 3rd servo through it, to pull and push the eye frame back and forth.  It works pretty well!  Let’s see how it works with the mask:

Well, there’s a couple problems. One is that the vertical movement servo has too much flex in the way it’s mounted.  When the movement of the eyes is obstructed or resisted at all by the mask, the servo flexes instead of moving the eyes.  I think if I add 2nd mount to the back of the servo, this should largely prevent the flexing.

The bigger problem is that in order to look up, the servos below the eyes end up protruding forwards quite a bit.  This means they end up hitting the mask, right in Yoda’s cheeks.  I think the best way to fix this is to remove the servos from under the eyes, and put a small gear there instead, that rotates around a bolt that’s attached to a bar coming forward from the main horizontal copper bar.  Then mounting the servo behind the eye, with a gear.  As an alternative to the gears, since the eye only needs a range of motion of about 150 degrees, I may be able to fashion some sort of linkage.  I’ll need to think about that a bit, and play around with some bits of wire before I commit to using some of my precious brass tubes.

Designing the tiny noisemaker

Noisemakers based on an ATmega328 or ATtiny45/85, and a small piezo speaker. From left to right, top to bottom: Version 1. First experiment with ATmega328, running with 16MHz crystal. Eventually used the 8MHz internal clock, to use less power. Crystal no longer needed. Version 2: Second experiment with ATmega328, without crystal. Down to 7 microamps of current draw when sleeping. Also omitted capacitor for power smoothing. Seems to work fine. Version 3: Switched to an ATtiny45 for it's smaller size. Also removed programming header. Need to remove chip to program now. Version 4: Final version. Using an ATtiny85 glued directly to a CR2032 battery holder. Added programming header back on, but only 4 pins. Need to use gator clips to attach power and ground for programming.
Progression of prototypes

In my previous post, I wrote about how I got the current draw on my noisemaker down to a small enough amount that it should be able to run for months. (More to come about battery life when my experiment is finished.) I didn’t originally start with an ATtiny45/85 though, so I thought I would write a bit about what I started with, and how the design changed as I went.

I started out, as I usually do, with an Arduino Uno. What I wanted to do originally was use PWM to play sounds on a piezo speaker. Timer1 is the library I found that let me do that. With that, I was able to get some pretty annoying beeping sounds out of that little piezo speaker.

Since I wanted to plant 8-10 of these in the office, $35 each for an Uno was way too much. I wanted to be able to make them for less than $10 each. To do this, I would need to get this working with a bare AVR chip and no external oscillator. This would also make them smaller and easier to hide.

My first step toward that goal was to reproduce the same circuit on a breadboard using an ATmega328. Without the USB-serial converter from the Uno, I would need to program it through the ICSP pins using my Arduino-ISP programmer.

Arduino ISP connected to breadboard with ATmega328
Arduino ISP connected to breadboard with ATmega328 (piezo not pictured)

Once this was working (which was pretty quick since this wasn’t the first time I had done this sort of thing) I decided to dead-bug a prototype. I was apprehensive about soldering directly to the chip though, because I’d never done it before, and I didn’t have any spare chips around. I did, however, have a whole bunch of 28-pin DIP sockets around, so I popped the chip into one of those, and soldered everything to that. Thus was born my first prototype:

Original prototype
Original prototype

Unfortunately, this prototype still required some kind of power source. I had neglected to consider that when I constructed it. I decided, possibly hastily, to come back to that later. In hindsight, the power supply is something I should consider early on in the design, considering how much it affected the final design. I decided instead to concentrate on the fact that it was also still using a fairly expensive (only $2, but it adds up when you’re making 10) crystal oscillator, and a large and expensive ATmega328. I knew from a previous project that by setting fuses, I could get the AVR to run without the need of the oscillator, so I set the appropriate fuses, and got it beeping away annoyingly without needing the oscillator. To prove it was working, I constructed a 2nd prototype, without the oscillator, or the two 20pf capacitors needed for the oscillator. I also decided to forgo the 10uf capacitor between GND and Vcc, trusting that whatever battery I used would be able to supply sufficiently ripply-free power to make it unnecessary.

Second prototype
Second prototype

The 3rd prototype was when I decided to try shrinking it in size and cost by using an ATtiny45. This presented a bit of a challenge since they don’t have a 16-bit timer, for the PWM sounds, like the ATmega328. Instead of trying to get things working with an 8-bit timer (which I’m not sure has the resolution for playing back notes and such) I ended up rewriting it all to just bit-bang the sounds out. This worked great, but I still had the problem of the power source to work out.

Third prototype
Third prototype

Somewhere along the way, I don’t actually remember when, I did all the work to get the power consumption down to tiny amounts. I also discovered that once I turned off the brownout protection as part of that, I was able to run the whole thing from a CR2032 coin-cell battery. I included the coin-cell holder in the photo above for scale. It’s much bigger than both the ATtiny and the piezo buzzer combined, so that gave me an idea: Why not glue the IC and piezo to the back of the battery holder, and wire it all up like that. A bit of playing around with different arrangements led me to this:

Final prototype of noisemaker
Final prototype of noisemaker

The CR2032 is only 3V, but at the clock speed I was running the AVR, and with brownout protection set low (or off, in my case), it runs fine at 3V. The only downside is that the piezo isn’t as loud as it was at 4.5 or 5 volts.

I’m actually quite proud of how this turned out, other than the diode. The IC, piezo, and 4-pin header are all glued to the back of the battery holder. Pins 5,6,7 (MOSI, MISO, SCK) are bent over flat so they touch the pins on the 4-pin header. The Vcc pin is bent, carefully, around sideways so it touches the positive terminal of the battery holder. The negative pin of the piezo buzzer is touching the negative terminal of the battery holder.

One of the leads on the resistor from Vcc to pin 1 (reset) is bent around down the center of the IC and over to the 4th pin on the 4-pin header, to make those 4 pins easily accessible for programming. Another resistor (for purposes I’ll explain shortly) is run from pin 7 to the IC’s ground pin, and that resistor lead also carries on to connect to the negative terminal of the battery.

Finally, a diode connects the positive terminal of the piezo buzzer to pin 2 on the IC. The first two prototypes connected the piezo directly to the IC. When I was working on the 3rd prototype, the first one to use an ATtiny, I got it working on a breadboard first. While I was working on the code for bit-banging the sounds, I noticed that some frequencies would cause the AVR to reset. I kind of suspect that a capacitor across the +/- terminals might fix that, but for some reason I didn’t try that at the time. I didn’t realize then that a piezo speaker isn’t (I think?) an inductive load, like a regular speaker would be, so I thought that maybe I needed a diode to prevent reverse current spikes. I’m not entirely sure why it fixed the problem, but it certainly seems to have fixed it.

Low power ATmega/tiny with watchdog timer

At work recently, the pranks have been escalating. I’ve decided that for my next salvo, I’m going to build the most annoying beeping device I can. I’m using an ATtiny45/85 chip, programmed using the Arduino development environment.


The clone army grows
The clone army grows

The device is intended to be planted somewhere near the target’s desk, and will just beep (or make some other annoying sound), every 5-8 minutes. In that respect, it’s very similar to the Annoy-a-tron that ThinkGeek sells. (Which was one of my previous salvos.)

Three primary factors influenced the design of this, in this order:

  1. Low power consumption
  2. Inexpensive
  3. Small size

It’s likely to take the subject days, if not weeks, to find it at that rate, so the battery needs to last for at least a few weeks. This means either having a huge battery pack, which would go against point #3, or making the AVR chip use very little power. Thankfully, there are some excellent resources out there about lowering power use on an AVR chip.

As I intend to make around 10 of these devices, keeping the cost down was important. In the end, this led to it drawing about 7 times as power as is possible to get it down to, but with a lower part count, which translates to lower cost. In particular, Sparkfun has an excellent tutorial on getting an AVR down to only 1 microamp of current draw, however this uses a 32KHz watch crystal, which I intended to do without.

Making this as small as possible was quite a challenge, but in the end, the largest parts were the battery and battery holder. This requirement led me away from the 28-pin DIP ATmega328 I prototyped with to an 8-pin DIP ATtiny45/85 that I used in the end. Even the piezo speaker I used is bigger than the AVR.

However, the most challenging part of this project for me was getting the power consumption down to a rate that would allow the CR2032 battery, chosen for it’s size, to power this for long enough. Most of what I learned about power saving I learned from the aforementioned Sparkfun tutorial, and the nightingale example from this page. I found there were 4 key things to getting an AVR to run at low power:

  1. Putting the chip to sleep when it’s idle. (delay() doesn’t do this.)
  2. Setting the clock speed low.
  3. Disabling any peripherals you’re not using
  4. Disabling brown-out protection.

1. Putting the chip to sleep when it’s idle.

Putting the chip to sleep is pretty easy:


But then you need some way to wake it up. The Sparkfun tutorial uses a 32.686kHz external clock crystal to run Timer2 and wake it up every 8 seconds. Since I’m trying to keep the cost down, I’m forgoing the use of an external clock crystal, so I need a different way to wake the chip back up. Instead, I’m using the internal watchdog timer to wake it up, which I learned about from the nightingale example. I copied the setup_watchdog function from that example and I call it in my setup(), with setup_watchdog(9) so that it wakes up every 8 seconds. When it wakes up, it then calls a function, which is defined like:

ISR(WDT_vect) {

watchdog_counter is a global variable in my program, used in loop() to keep track of how many times the watchdog has been called.

The loop looks something like:

void loop() {
  // ZZzz....
  if (watchdog_counter >= 60) {
    watchdog_counter = 0;

When sleep_mode() is called, the chip goes to sleep, and drops down to much lower current draw. Approximately 8 seconds later, the watchdog wakes it up, and calls the function defined with ISR(WDT_vect). Once that function returns, the loop() function continues again by returning from the call to sleep_mode(). At this point then, the code runs as you would expect it to. It continues on the next line, which checks the counter. If it’s high enough, it calls annoy() and makes annoying noises. When it reaches the bottom of the loop, and continues again at the top, it calls sleep_mode() and goes back to sleep. So to summarize: every 8 seconds it gets woken up, loop() comes out of it’s coma, checks if it’s time to make noise, and then goes back to sleep.

That alone has a dramatic effect on the power usage, but to really get it low, there’s three more things to do.

2. Setting the clock speed low.

The ATmega328 on the Arduino Uno runs at 16MHz. This is great when you care more about getting things done quickly than about power use. For my application, it’s much faster than I need, so I’m happy to sacrifice some speed if it’ll use less power. As a result, my chip is only running at 8MHz. It’s also using the internal oscillator for this, instead of an external clock crystal, to save parts, and lower the cost.

To change the clock speed, and to make it use the internal oscillator, you need an AVR programmer of some sort. There are many AVR programmers out there, but since I had a few spare Arduino boards kicking around, I’m using the Arduino-ISP sketch to turn one of them into a programmer. My ATMega328 is on a breadboard, with the minimum supporting hardware for it to run.

Changing things like the clock speed is done by setting “fuses”. If you haven’t set fuses before, keep this in mind: Setting fuses wrong can do (almost) irreversible things like disabling programming. With that warning in mind, Adafruit has some good info about using avrdude to set fuses.

As far as I’ve been able to determine, this only affects the power usage of the chip when it’s awake.  While it’s sleeping, the clock speed doesn’t appear to have any effect on the current draw.

I’m using E2 for lfuse on an ATyiny85, to set a 8MHz clock.  Lowering it to 1MHz didn’t make much of a difference in power use.

3. Disabling any peripherals you’re not using

With the chip asleep, and the clock at 8MHz, it was still drawing 330 microamps.

The Sparkfun tutorial had some examples of how to disable various parts of the chip.  This can all be done in the code. The code from the example is intended for an ATmega328, so not all of it applies to the ATtiny85.  This is the only part that had any effect on the current draw while asleep for me:

ADCSRA &= ~(1<<ADEN); //Disable ADC
ACSR = (1<<ACD); //Disable the analog comparator
DIDR0 = 0x3F; //Disable digital input buffers on all ADC0-ADC5 pins.

4. Disabling brown-out protection.

At this point, the current draw when asleep was 30 microamps.  Still higher than I wanted.

The trick, which again I learned from the SparkFun tutorial, was to disable brown-out protection.  It’s pretty easy to do, once you already know how to set fuses. I’m just setting efuse to 07 (or FF, which is the same thing) to disable brownout protection.

With all that done, it’s drawing 0.007ma when it’s sleeping, and about 7ma when it’s actually beeping.  7 microamps is exactly what the ATtiny85 datasheet (figure22-12) claims it should draw at 5 volts in power-down mode, with the watchdog timer running, at 25°C.

I suppose one thing that’s worth mentioning is that my circuit is ridiculously simple, so there’s nothing else that could end up drawing extra power. I have a 10k resistor from the reset pin to the Vcc pin, and a piezo speaker connected to a digital output pin, and ground. I have a stack of coin cell batteries connected to Vcc and ground, without any capacitors or anything. It’s been working just fine that way.

More info about power usage to come in a future blog post.