Introduction: Water Squirting, Twitter Enabled Intruder Detector!

What's better than a motion detector for home security? A tweeting motion detector that can spray water!

In this project, we will build a water spraying intruder alarm using a Lightblue Bean (a BLE enabled Arduino micro controller) equipped with a PIR motion sensor. After spraying the intruder, the Lightblue Bean will trigger a nearby computer to take a picture, and upload it to Twitter. We will also be able to remotely arm or disarm the motion detector by sending messages to the system through Twitter.

This project uses the power of Node-RED and Python to capture images and to connect the system to Twitter.

Check out some action shots! -

Step 1: Parts and Tools

You will need:


  • Soldering iron
  • Screw driver
  • Drill/dremel tool


Step 2: Hack the Water Gun

The water gun has a motorized pump. We will use a MOSFET to drive its motor so that the gun can be controlled by the Bean.

  1. Remove all the screws to open the water gun
  2. There are two wires going from the battery compartment to the pump motor. Cut the black wire, and solder two long pieces of wire to each end
  3. Connect a diode across the power supply to protect our circuit from the reverse EMF generated by the DC motor. Strip the red wire, and connect a diode between the red and black wires, making sure the polarity is reversed. The cathode (negative terminal) of the diode should be connected to the red wire, and the other end to the black wire
  4. Tape the contacts to prevent short circuits
  5. Drill a small hole on the underside of the gun to slip the wires out
  6. Screw everything back together
  7. Tape the trigger to keep it pressed

Step 3: Build the Circuit

So, what is going on here is that when the PIR sensor detects motion, it sends a signal to a pin on the Bean. The code on the Bean then sends a signal to the MOSFET to switch it on. The MOSFET works like a switch and turns on the water gun’s pump motor.

MOSFETs as switches: A MOSFET has “Gate”, “Drain” and “Source” terminals (in the diagram above, the left terminal is the Gate, the middle one is Drain, and the right terminal is Source). The Gate-Source voltage difference controls the Drain-Source resistance. When there is no voltage difference between the Gate-Source pins, the Drain-Source resistance will be very high (open circuit), and vice versa. In our circuit, the Gate pin is pulled low with a 10K resistor. So, there is no voltage difference between Gate-Source. To switch it on, the Bean sends a signal to the Gate pin to increase the Gate-Source voltage difference. This reduces the Drain-Source resistance (closed circuit), and fires the water gun.

Using the PIR sensor: If you are using the PIR sensor from Sparkfun, be careful not to fall for the manufacturer’s trap – the black wire is NOT ground! The black wire is actually the signal wire. The ground will either be a white wire, or a brown wire. The PIR sensor from Sparkfun is an open collector, which means we need to put a pull-up resistor on the signal pin. Also, the sensor needs 5-12V (more than the Bean can supply), so we are powering it with four AA batteries. The PIR sensor has a wide coverage area. To give it a more directional sight, put the sensor module inside an empty toilet paper roll.

Step 4: Program the Bean

Read the Lightblue Bean "Getting Started" before you proceed.

The code on the Bean basically just monitors the PIR sensor’s output, and fires the gun when it detects motion. It also wirelessly communicates with our computer, so that it can be remotely enabled or disabled, or to indicate when it detects motion. The code on our computer can then take a picture and upload it to Twitter.

There are 4 commands that we can send to the Bean:

  • 00 – Disables everything
  • 01 – Only enables the water gun
  • 10 – Only sends a signal when it detects motion (so that the computer can take a picture), but does not fire the gun
  • 11 – Enables the gun, and also sends a signal to the computer when it detects motion

If taking pictures is enabled, the Bean sends the character “1” to the computer (using the serial command) whenever it detects motion (line 95).

Step 5: Start Node-RED Server

Install the Bean nodes for Node-RED before moving on.

Go the terminal and start node-red

$ node-red

Welcome to Node-RED

25 Feb 22:51:09 - [info] Node-RED version: v0.10.6
25 Feb 22:51:09 - [info] Node.js  version: v0.10.36
25 Feb 22:51:09 - [info] Loading palette nodes
25 Feb 22:51:10 - [warn] ------------------------------------------
25 Feb 22:51:10 - [warn] Failed to register 5 node types
25 Feb 22:51:10 - [warn] Run with -v for details
25 Feb 22:51:10 - [warn] ------------------------------------------
25 Feb 22:51:10 - [info] User Directory : /home/nol/.node-red
25 Feb 22:51:10 - [info] Server now running at
25 Feb 22:51:10 - [info] Creating new flows file : flows_noltop.json
25 Feb 22:51:10 - [info] Starting flows
25 Feb 22:51:10 - [info] Started flows

Step 6: Import Node-RED Flow

  1. Open http://localhost:1880/ in your web browser
  2. Copy JSON code given below
  3. Click the menu button on the top right corner and select import > clipboard and paste the JSON code
[{"id":"4f7a7d17.b08584","type":"bean","name":"meanbean","uuid":"","connectiontype":"constant","connectiontimeout":"0"},{"id":"45c62790.ba39d8","type":"bean serial","name":"Bean serial","bean":"4f7a7d17.b08584","newline":"\\n","bin":"false","out":"char","addchar":true,"x":86.66666412353516,"y":268.8888854980469,"z":"5ed181e8.a12e8","wires":[["7ee00806.811ff8"]]},{"id":"7ee00806.811ff8","type":"switch","name":"Check motion","property":"payload","rules":[{"t":"eq","v":"1"}],"checkall":"true","outputs":1,"x":253.66666412353516,"y":268.8888854980469,"z":"5ed181e8.a12e8","wires":[["de364926.21c9b8","c1d68100.3e298"]]},{"id":"de364926.21c9b8","type":"change","name":"","rules":[{"t":"set","p":"payload","to":"1"}],"action":"","property":"","from":"","to":"","reg":false,"x":440.6666717529297,"y":231.1388874053955,"z":"5ed181e8.a12e8","wires":[["28bd047.fd742fc"]]},{"id":"fd8cf1a2.02731","type":"function","name":"Extract password and command","func":"if (msg.payload.length == 6)\n{\n    var pwd = msg.payload.substring(0,4);\n    var cmd = msg.payload.substring(4,6);\n    \n    msg.payload = {};\n    msg.payload.pwd = pwd;\n    msg.payload.cmd = cmd;\n    \n    return msg;\n}\nreturn null;","outputs":1,"valid":true,"x":365.66666412353516,"y":423.5555419921875,"z":"5ed181e8.a12e8","wires":[["a396029a.5c6a"]]},{"id":"a396029a.5c6a","type":"switch","name":"Verify password","property":"payload.pwd","rules":[{"t":"eq","v":"1234"}],"checkall":"true","outputs":1,"x":603.6666641235352,"y":423.5555419921875,"z":"5ed181e8.a12e8","wires":[["5823ab3e.a7dc54"]]},{"id":"5823ab3e.a7dc54","type":"change","name":"","rules":[{"t":"set","p":"payload","to":"msg.payload.cmd"}],"action":"","property":"","from":"","to":"","reg":false,"x":796.6666641235352,"y":423.5555419921875,"z":"5ed181e8.a12e8","wires":[["11a116da.ee5ee9","2f12e66a.d0ed1a","5f46d32d.a0b92c"]]},{"id":"58eb0b09.a714f4","type":"twitter in","twitter":"","tags":"","user":"dm","name":"","topic":"tweets","x":97.66666412353516,"y":423.2221984863281,"z":"5ed181e8.a12e8","wires":[["fd8cf1a2.02731"]]},{"id":"11a116da.ee5ee9","type":"debug","name":"","active":true,"console":"false","complete":"false","x":988.4166793823242,"y":486.8888912200928,"z":"5ed181e8.a12e8","wires":[]},{"id":"2f12e66a.d0ed1a","type":"bean serial","name":"Bean serial","bean":"4f7a7d17.b08584","newline":"\\n","bin":"false","out":"char","addchar":false,"x":986.6666793823242,"y":423.13888931274414,"z":"5ed181e8.a12e8","wires":[[]]},{"id":"2db5ea45.d24a16","type":"exec","command":"python","addpay":true,"append":"/Users/ashish/Documents/MotionDetector/","useSpawn":false,"name":"Upload to twitter","x":781.4166641235352,"y":315.8888854980469,"z":"5ed181e8.a12e8","wires":[[],[],[]]},{"id":"5f46d32d.a0b92c","type":"switch","name":"Turn on camera?","property":"payload","rules":[{"t":"eq","v":"10"},{"t":"eq","v":"11"},{"t":"eq","v":"00"},{"t":"eq","v":"01"}],"checkall":"true","outputs":4,"x":999.6666641235352,"y":357.8888854980469,"z":"5ed181e8.a12e8","wires":[["3314ac40.cceb54"],["3314ac40.cceb54"],["c76d9c3e.38926"],["c76d9c3e.38926"]]},{"id":"a775d7eb.588a28","type":"exec","command":"python","addpay":true,"append":"/Users/ashish/Documents/MotionDetector/","useSpawn":"","name":"Start camera","x":1406.6666641235352,"y":319.8888854980469,"z":"5ed181e8.a12e8","wires":[[],[],[]]},{"id":"53a9f805.ac5608","type":"udp out","name":"Stop camera","addr":"localhost","iface":"","port":"5005","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":1404.6666641235352,"y":396.8888854980469,"z":"5ed181e8.a12e8","wires":[]},{"id":"c76d9c3e.38926","type":"change","name":"","rules":[{"t":"set","p":"payload","to":"0"}],"action":"","property":"","from":"","to":"","reg":false,"x":1213.6666641235352,"y":396.8888854980469,"z":"5ed181e8.a12e8","wires":[["53a9f805.ac5608"]]},{"id":"3314ac40.cceb54","type":"change","name":"","rules":[{"t":"set","p":"payload","to":""}],"action":"","property":"","from":"","to":"","reg":false,"x":1210.6666641235352,"y":319.8888854980469,"z":"5ed181e8.a12e8","wires":[["a775d7eb.588a28"]]},{"id":"762ac427.89d53c","type":"udp out","name":"Take picture","addr":"localhost","iface":"","port":"5005","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":767.6666641235352,"y":230.88888549804688,"z":"5ed181e8.a12e8","wires":[]},{"id":"43ccb64.fbc3348","type":"inject","name":"disarm","topic":"","payload":"123400","payloadType":"string","repeat":"","crontab":"","once":false,"x":87.66666412353516,"y":366.8888854980469,"z":"5ed181e8.a12e8","wires":[["fd8cf1a2.02731"]]},{"id":"fb624da.f049db","type":"inject","name":"enable gun+camera","topic":"","payload":"123411","payloadType":"string","repeat":"","crontab":"","once":false,"x":120.41666412353516,"y":478.8888897895813,"z":"5ed181e8.a12e8","wires":[["fd8cf1a2.02731"]]},{"id":"78e2552e.871dac","type":"inject","name":"enable camera only","topic":"","payload":"123410","payloadType":"string","repeat":"","crontab":"","once":false,"x":155.66666412353516,"y":533.8888854980469,"z":"5ed181e8.a12e8","wires":[["fd8cf1a2.02731"]]},{"id":"22191388.dde6ec","type":"inject","name":"enable gun only","topic":"","payload":"123401","payloadType":"string","repeat":"","crontab":"","once":false,"x":217.66666412353516,"y":591.8888854980469,"z":"5ed181e8.a12e8","wires":[["fd8cf1a2.02731"]]},{"id":"28bd047.fd742fc","type":"delay","name":"","pauseType":"delay","timeout":"0.5","timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":609.6666641235352,"y":230.88888549804688,"z":"5ed181e8.a12e8","wires":[["762ac427.89d53c"]]},{"id":"c1d68100.3e298","type":"delay","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":422.66666412353516,"y":315.8888854980469,"z":"5ed181e8.a12e8","wires":[["3466c14b.cb993e"]]},{"id":"3466c14b.cb993e","type":"change","name":"","rules":[{"t":"set","p":"payload","to":""}],"action":"","property":"","from":"","to":"","reg":false,"x":594.6666641235352,"y":315.8888854980469,"z":"5ed181e8.a12e8","wires":[["2db5ea45.d24a16"]]}]

Step 7: Change Bean Name and Link Twitter Account

  1. Double click the Bean nodes and click on the pen to edit the Bean settings. Update the name to be the name of your Bean. It is important you write the exact name as it’s the only way for Node-RED to find and connect to the correct Bean.
  2. Double click the tweet node and choose “add new Twitter credentials” to connect to the Twitter account you want to use. Choose what you want to monitor: direct messages.

Step 8: Understanding the Node-RED Flow

The Node-RED flow does two things – 1. It monitors the Bean’s serial. If it receives a command to take a photo (character ‘1’), it takes a photo and uploads it to Twitter. 2. It checks the Bean’s Twitter account for direct messages. If it receives a message, it parses it, verifies the password, and passes the command to the Bean.

Twitter messages to the Bean should contain 6 digits. The first 4 digits make up the password, and the last two digits is the command you want to pass to the Bean. For example, if your password is “1234”, and you want to enable the gun and take pictures, you would send “123411” to the Bean’s Twitter account. To disable everything, send “123400” (see list of commands above). There are also inject nodes that can be used to control the Bean directly with Node-RED without using Twitter. This is also a good way to test if everything is working!

To change your password to something better, just modify the value in the “Verify password” node. Make sure you modify the inject nodes accordingly.

Step 9: Python Script for Taking Pictures

  • We will use a Python script to take pictures whenever the Bean detects motion. It will keep the camera on when taking pictures is enabled, and it will communicate with our Node-RED flow using UDP. When Node-RED sends a signal to take a picture, this script will do that.
  • This script relies on the OpenCV library to capture images from the webcam. Here is an tutorial on installing OpenCV on a Mac –
  • Make sure to modify the folder_path variable to point to the folder where you want to save the images. Also, change the “Start camera” exec node in Node-RED to point to this Python script.

Step 10: Python Script for Uploading Pictures to Twitter

  • This script uses the tweepy package to upload to Twitter. Make sure it is installed –
  • You have to register your app and fill in your consumer key, access token etc in the above code. Register your twitter app by going here –
  • The folder_path variable should point to the folder where you are saving images. The “Upload to twitter” exec node in Node-RED should point to this Python script.

Step 11: Deploy!

Click deploy in the top right corner of the Node-RED page to start the flow. Enjoy spraying people!

Home Automation

Runner Up in the
Home Automation