Annoy-o-tron Tiny

The (in)famous beeping prank made as small as possible

Similar projects worth following
ThinkGeek once upon a time sold a device they called the Annoy-o-tron. It was just a small battery powered thing that beeped once in a while. You were meant to hide it somewhere to annoy someone. Many folks have designed and made similar devices. This is one intended to be as small as possible.

The hardware is quite simple - it's a microcontroller connected to a piezoelectric speaker and a battery. In this case, the controller is the ATTiny9, which comes as a SOT23-6. It's connected to a 12MM coin cell battery bail and a 12.5mm piezo element. There's also a TPI interface on the board for updating the firmware.

Where this project gets complex is the firmware. A CR1225 has just under 50 mAh of power and you want to have the controller use as little of that as possible most of the time. If you clock the Tiny9 at 500 kHz then the idle consumption is something like 15 µA, which means that this project, in principle, should be able to last around 4 months on a battery.

When the controller wakes up, it generates a quarter-second tone of one of 5 frequencies. It then sleeps for a random period of time between 30 and 60 minutes and does it again. The random time means that the prank's target can't anticipate it and be ready to listen for where it's coming from, which will make it that much harder to find.

The first cut of the circuit board is 3/4" square. On the bottom is the battery clip, and straddling that, the speaker. The top has everything else, but is mostly flat, facilitating the placement of a piece of foam or magnetic tape.

application/pdf - 11.80 kB - 06/27/2020 at 19:11


sch - 80.16 kB - 06/27/2020 at 19:10


brd - 37.05 kB - 06/27/2020 at 19:10


  • Another improvement

    Nick Sayer06/27/2020 at 19:09 0 comments

    The 1.0 boards are being built now, but I've already had an idea for a 1.1 improvement.

    With 1.0, one pin of the controller is connected to the piezo element and the other lead of the element is grounded. This means that the piezo will see a 3 volt square wave.

    Instead, v1.1 hooks one pin of the controller to each side of the element and it is fed with two square waves 180º out of phase. In this manner the piezo element effectively sees a square wave with a peak-to-peak amplitude of 6 volts.

    Previously, I was careful to use pin B2, which is the only pin not involved in TPI on the chip. By using two pins, it forces us to use one of those TPI pins. But B2 will be high impedance during programming, so this isn't as big a deal as it might seem - the piezo will effectively have one side disconnected and the other won't therefore load the programming pin.

    The code doesn't have to change much. There are already instructions to set up the DDR register, toggle the pin and clear it when the beeping is done. In principle these instructions simply need to have the constants changed to have two bits set instead of one. The one extra instruction needed is to set one (but not both) pins to 1 at the start of the beeping. From then on, toggling both will result in the out-of-phase square waves we want. At the end, both outputs are set low. As before, the remaining (non !RESET) pin is set to be an input with the pull-up turned on. This will minimize power consumption.

  • Low rider

    Nick Sayer06/26/2020 at 22:36 0 comments

    Well, I had an opportunity to to put the prototype on my µCurrent and it came back at something like 90 µA, which seemed quite high to me.

    The challenge is that you want to have a relatively fast clock while beeping so that you can run lots of instructions between pin toggles (yes, I could have used the timer PWM output instead of toggling a pin by hand, but those pins are shared with the programming interface, and it's just a whole lot easier to put low impedance or capacitive loads on the unshared B2).

    Well, since you can switch clock sources and prescaling on the fly, I decided to use differential clocking. So we use the 8 MHz oscillator pre-scaled by 8 for beeping (1 MHz), and use the 128 kHz oscillator pre-scaled by 1 for the long wait periods. During the wait, we set up the timer with a divide-by-1024 prescale itself, and wait 1250 counts - 10 seconds - between interrupts. With this, the long term current draw seems to be approximately 7 µA - astonishingly low. In principle, the battery could last almost a year, except that the actual beeping is going to cost something. Still, if we assume a draw of 5 mA during beeping, and we beep for 1/4 second, that's about 350 nAH per beep, or well over 100,000 beeps on one battery (since the active current required by the Tiny9 at 1 MHz and 3 volts is around 300 µA, most of the assumed power is for the speaker).

  • Prototype success

    Nick Sayer06/26/2020 at 20:14 0 comments

    The boards aren't back from OSHPark yet, but I decided to take an old AC Timer board board and just use it to hold an ATTiny to test out the firmware.

    I'm happy to report that that done the firmware works perfectly. It does take up almost all of the available flash space of an ATTiny9, but that's more or less because you have to trade flash for RAM by having every function be always-inline and save the stack for the ISR call and return. Most of the space, however, is taken up by the PRNG. It's the same one used for the Crazy Clock and uses 32 bit operations, which necessitates adding the 32 bit math. Using 16 bit values would probably reduce the size by 25%, but at least at the moment there's no driving need.

    I haven't verified the low current draw just yet, but I anticipate that won't result in any surprises.

View all 3 project logs

Enjoy this project?



Lee wrote 07/22/2021 at 09:19 point

Hello Nick,

I recently purchased this Annoy-o-Tron and it doesn't seem to work as advertised. After a period of time, the board starts to emit very regular beeps at approximately 5 second intervals, at which point it becomes incredibly easy to find.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates