At ThinkGeek, there's a cool little Annoy-a-tron for sale; the original was a tiny little coin-cell battery device that beeped every so often (every minute or so) just to make your coworkers go crazy. I have a Raspberry Pi and a Pibrella, I am sure I can take that Annoy-a-tron idea and improve upon it...!

In the end, the code is rather simple and basic (or so I think). This was more of an excercise in coding in Python and setting up a simple git repository, rather than coding "the perfect" annoyance or Python script.

To start, a quick description of the original Annoy-a-tron, and how the Annoy-Pi improves upon it.

The original Annoy-a-tron was a tiny little device, hardly bigger than the coin-cell battery that runs it, and it emitted a high-pitched beep every minute or so. The nice thing about this was that it was battery operated, and pysically tiny, so it could be mounted with double-sided tape just about anywhere, under a desk or chair, just inside ceiling tiles, etc... I have lived through such a prank (not immediately directed towards me though), and can attest to how small and easily hidden this can be. The problem with it (in my opinion), is that is somewhat easily identified, though not so easily found. Since this little device emits the same pitch at the same regular interval, once you hear it a few times, you know what to expect, and can star to anticipate the beeping and slowly narrow in on it. In the end, these typically don't last much more than a day, or a couple of days if it is very craftily hidden.

The Annoy-Pi, on the other hand, pseudo-randomizes these details... It is a random pitch, that lasts for a random amount of time, with a random delay between the beeps. This prevents not only any ability to anticipate the beeps, but an ability to truly identify what might be going on... Since the beeps are noticeably different, the 'victim' cannot immediately identify that it's coming from the same thing, and instead chalk it up to something else entirely. Some of the beeps are so short and high-pitched, that you wonder if you just heard something, rather than long enough to truly hear and register. If anything, my coworkers have found this to be far MORE aggravating than just a regular tone and interval.

Another thing this was to accomplish, is an exercise with git. Despite how popular and prevalent git seems to be, I have never used it beyond cloning so I could download some code. I once forked some code to add a randomization feature to some code, but I followed a step-by-step guide, so it was pretty tough to mess up. This time, however, I'm going in blind, and trying to work it out for myself.. so if there are any github experts out there, cringing at my efforts, please be gentle...lol... At the time of writing, the code is available at https://github.com/jdmoore0883/Annoy-Pi. Please, take a look there for the actual download and code. Forgive the seeming lack of completeness there as I'm still figuring out git and github.

Finally, he last thing I really wanted to touch on with this script was the idea of threading, which would eventually lead to multi-threading (but I'm not quite there yet). I have some plans/projects in mind (that still require much fleshing out) that would have need of multithreading, so this is a nice exercise in learning.

Since the code is freely available on GitHub, I won't go through the ENTIRE script... instead, I'll just go over a couple of key details to describe what's going on.

time.sleep(random.uniform(2, 5)*60)

This takes place right at the start of the script; once started, wait 2-5 minutes before actually starting. Ideally, this script would be set to run as a cron job at boot time, so this gives you 2-5 minutes to run off before it starts beeping.

def carry_on():

Some code to determine whether or not to continue beeping. The way I got the rest of the code to work may have rendered this function redundant or useless (see next code)... But I wanted to have the beeping function running as a separate thread, and wanted a way to tell it it continue running, or stop; this was my solution.

def button_changed(pin):

This is the code for the button push. Initially, I had it set the file content to False, so that when the button was pressed, the beeping would stop. Problem was, that when the button was pressed, we had to wait until the next beep would take place; up to 5 minutes max. Rather than wait like that, I just had the button press issue the shutdown command.

def beep():

This is the meat of the script; this is where we deifine the tone, length of tone, and wait time between beeps.


I used this to denote where the script itself starts, since everything above it is function definitions only.


To be absolutely honest, I'm not 100% what this does... I know it does something about watching (or joining) the thread(s) I had started. But what I DO know is this: I put this in here to "stop" or "pause" the script, so that it would not just end while the thread is running, and then close the threrad because the whole thing is closing out. This (somehow) prevents the script from closing out until the thread has completed.


In the end, I am sure there are a few things that can be improved upon, and if you see something, fork my github project and fix it, or just let me know in the comments section below. Let me know how you have set up YOUR Pi to drive someone crazy! I would love to hear from you.

Add comment

Security code