Update, 5/26/23: The robot worked so well I have declared victory over the squirrels .

It’s a classic American story. We bought a house in the suburbs. I set up a birdfeeder. Then, I found myself fighting a vendetta against the squirrels.

The dastardly squirrels were stealing the birdseed. Darn you to heck, squirrels!

A traditional solution, putting chile powder in the birdseed, didn’t work. Home Depot didn’t have a squirrel baffle that fit the pole my birdfeed hangs on. Lesser men would have given up — or bought an appropriate baffle on Amazon — but I am stronger than that.

That’s why I built the Squirrel Soaker 9000.

With about $50 in parts, I built a robot that uses AI to see if there’s a squirrel at the feeder — and when it sees one, sprays it with water from the a garden hose.

And, of course, it takes a video of the panicked squirrel fleeing. Here’s a few highlights:

It really does work, with the number of squirrels at the feeder declining since I activated the Squirrel Soaker 9000 — all without harming the squirrels. Plus, it’s a much safer solution than what my great-grandfather — a North Florida redneck by way of Saskatchewan and Russia — built 60 years ago: 120V wires strung in his fruit trees.

Here’s how it works:

  1. Every thirty seconds, my custom Python software takes a picture.
  2. It sends that picture to a AWS Lambda endpoint that classifies the photo according to a fast.ai model I trained to detect if the picture shows a squirrel on the feeder or not.
  3. If the model says there’s a squirrel, then
    1. start recording a video
    2. send a signal to the an electronically-controlled on-off switch called a MOSFET
    3. which in turns turns on the 12V power for a few seconds to the solenoid valve, essentially an electrically-controlled faucet, that is hooked up to a garden sprayer zip-tied to a tomato cage.

Does it work? Does it repel squirrels?

Yes! Did you even watch the video?

Oh you mean systematically? Also yes, it reduces squirrel visits by about one visit per three days, on average. That’s not as much of an improvement as I hoped.

A chart with a decreasing trend line.

Look at that trend line, just look at it.

At some point in October, the squirrels stopped coming at all. I’m not sure if they were repelled by the Squirrel Soaker or just distracted by other, tastier autumnal treats.

Is it still running?

I turned it off for winter, since I don’t want the pipes freezing, but it’ll be back in after the last frost.

Does it repel birds?


Precision is about 86.6% percent, meaning that when the Squirrel Soaker 9000 sprays, 86.6% of the time, there’s a squirrel. 13.4% of the time, it’s something else. Usually a bird, sometimes nothing… or sometimes me.

That’s calculated over a 15 day sample of 321 fires, of which 43 were mistakes.

The AI tends to mistake mourning doves, in particular, for squirrels. They’re both big and gray, I guess? (They also only began showing up in my backyard on the feeder after I gathered the training data for the AI model — so in essence I’m asking a stupid AI that’s never seen a mourning dove whether a mourning dove is a sparrow or a squirrel. Occasionally the AI says it’s a squirrel. What can ya do.)

One day, the Squirrel Soaker 9000 started spraying almost constantly, whether there was a squirrel, a bird or nothing on the feeder. The next day, it went back to normal, on its own. What gives?

A photo of a mourning dove on a birdfeeder.

Is there a squirrel on the feeder, or is there either a sparrow nothing on the feeder? It's gotta be one or the other.

A photograph of a tomato plant blocking the view of the birdfeeder.

Same question. One or other other.

Turns out, a tomato plant had grown a branch in front of the camera, blocking the bottom of the feeder where squirrels tend to hang out. If you ask a model that only knows about squirrels and birdfeeders whether a tomato plant is a squirrel or not… well, it decided it is. The next day, the plant had grown up and out of the way.

(Recall is like 99%, meaning that if there’s a squirrel on the feeder, it’s gonna get wet.)

Here’s how you could set up the electronics and plumbing bits:

First, assemble the power supply and MOSFET boards per their instructions; be sure your Raspberry Pi is up and running and connected to wifi.

The power connector outputs 12V, 5V and a common ground. The 12V wire and the ground go to the + and - inputs on the “System” side of the MOSFET. (Optionally, you can power the Raspberry Pi from the same power supply by connecting the 5V output to the Pi’s 5V pin and the ground to the Pi’s ground pin.)

Then, you wire up a GPIO pin from the Raspberry Pi to the C (for “Control”) input of the MOSFET. When this wire sends the HIGH voltage, then the MOSFET is open, sending 12V to the output (the “device” side); when the LOW voltage is sent, then the MOSFET is closed and no power goes to the device.

Also, wire the device side to the solenoid valve, using a very very long wire, so you can keep the electronics inside and the hose outside. Doesn’t matter the polarity, so hook up the positive wire to either side, but be sure to add a diode in parallel to stop flyback voltage spikes. (I had never heard of this!)

Now, you’re done with the electronics. On to plumbing!

Hook up your garden hose to the female-to-female hose adapter, then to the solenoid. The solenoid has an arrow showing the direction of water flow, so the arrow should point away from the water supply.

You may need to apply plumber’s tape to the input threads of the solenoid. The solenoid’s threads are British Standard Pipe, Parallel threads (aka BSPP, or G), in contrast with America’s garden hose threads. They mostly fit, but not perfectly — and the plumber’s tape will help stop leaks.

Same with the squirt nozzle — apply tape, then screw the nozzle on as usual.

Don’t turn the hose on all the way. That might put through too much pressure, causing leaks — or even causing the joints to blast apart. (I spent hours debugging the leaks and ruing my lack of plumbing knowledge… until I discovered this trick.)

Now we’re done with the plumbing.

On to software. You can send HIGH voltage to the control input of the MOSFET any way you want. I set up a button to do it manually, in addition to controlling it with software.

Once the model’s trained, I deployed the model to AWS Lambda along the lines of these two AWS tutorials: https://aws.amazon.com/blogs/machine-learning/using-container-images-to-run-pytorch-models-in-aws-lambda/, https://aws.amazon.com/blogs/compute/handling-binary-data-using-amazon-api-gateway-http-apis/.

The on-device script is a simple Python script with a while loop that, during daylight hours, takes a photo every thirty seconds, sends it to the model and, if the confidence that it’s a squirrel is over 70%, takes a photo (so I can verify if there was truly a squirrel present), records a video (for lulz), records the timing to a database, then opens the solenoid. That script is here.

I also have a tiny Flask app that shows the most recent photograph and an HTML button to manually control the solenoid via the network.

Here’s how I trained the AI model:

Fastai makes it really really easy — seriously, 13 lines of code — to cause an AI model to learn how to distinguish two kinds of pictures, by giving it examples of both kinds of pictures. I generated my training data (the examples) by taking a picture out my window every minute for a few days. Then, I downloaded those pictures and sorted them into “squirrel” and “not squirrel” folders using the filmstrip view of Mac Finder.

Then, I trained the model (for free, in 13 lines of code, in about 45 minutes) on Google Colab.

Materials list:

Tools list:

  • Soldering iron, solder
  • Multimeter
  • Google Colab, free
  • Fast.ai / Python
  • AWS Lambda (cheap or free)