Basic Raspberry Pi Home Wifi Router

The Goal of This Post:

This post is an extension to Jacob Salema’s Guide that was picked up by Lifehacker. My main issue with his post is that he refers to the end result as a wireless router, which is not entirely accurate. This device is not meant to be internet-facing and is really more of a wireless/ethernet bridge with the configurations provided.

My goal here was to extend what was provided in his initial post and make it suitable for placing a Raspberry Pi directly behind a cable modem and fully exposed to the internet.

image kindly borrowed from adafruit


  • Raspberry Pi B (gen 2 model) any Raspberry Pi could potentially work here though
  • Edimax EW-7811Un
  • Short piece of Ethernet (to connect to cable modem)
  • Power Adapter and cord for Pi
  • SD card with Raspbian installed
  • (Optional) USB Keyboard and HDMI Monitor to access the PI. All of these steps can be performed over SSH with a little creativity however.


The Raspberry Pi’s performance is limited by the USB throughput of the WLAN adapter; which on the Raspberry Pi is a USB2.0 hub limited to a theoretical maximum of 480mbps, so you’ll never be able to pull gigabit ethernet here but this will get the job done for small sites. However if you have really crappy broadband like I do in this location the chokepoint will be the crappy broadband and not the Raspberry Pi.

I have maxed out my crappy broadband connection with the following performance results:

A BLAZING — 2.78mbps download
A SIMILARLY BLAZING — 1.28mbps upload

I repeated the same tests using a top-notch Lenovo X1 Gen3 laptop and got the exact same results so there is no lag using the raspberry pi here (for this crappy broadband connection). Since my broadband is so crappy here I’m using 802.11G wifi which won’t choke anything.

Note: I probably wouldn’t trust this for anything over 10mbps. I think the Raspberry Pi 2 with 802.11n wifi could handle a standard 40mbps connection based on some of the numbers I’m seeing here.

1). Required Installs:

Perform these first before any of the other steps.

sudo apt-get update -y
sudo apt-get install rfkill zd1211-firmware hostapd hostap-utils iw dnsmasq bridge-utils -y


2). Interfaces Configuration (/etc/network/interfaces):

Modify the interfaces file (/etc/network/interfaces) as shown below.

allow-hotplug wlan0
allow-hotplug eth0

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
auto wlan0
iface wlan0 inet static

3). DNSmasq Configuration (/etc/dnsmasq.conf):

Modify the DNSmasq configuration file to look exactly like what you see below.

Feel free to modify your domain.

4). HostAPD Configuration (/etc/hostapd/hostapd.conf):

Modify the configuration file for hostapd to have the following content.

Notice we’re using the “hw_mode=g” option here this is because my limited internet connection couldn’t support max throughput of a wifi-N connection so there would be minimal benefit. If you’re interested in N and have a Raspberry Pi2 and a faster internet connection it may make sense to enable that in your scenario.

Also feel free to modify the SSID to whatever you like and modify the password too, you’ll need at least 8 characters for the password. The channel can also be set to any value between 1-14 (1,6,11,14 are common in the USA)


5). HostAPD Default Configuration (/etc/default/hostapd):

Modify the defaults file for hostapd (/etc/default/hostapd) to have the same DAEMON_CONF line. The type of quotes used to surround the /etc/hostapd/hostapd.conf file are mission critical; if you use the wrong kind of quotes, hostapd will not start. You can debug the start of hostapd with the command “hostapd -d /etc/hostapd/hostapd.conf” which puts it into debugging mode.

# Defaults for hostapd initscript
# See /usr/share/doc/hostapd/README.Debian for information about alternative
# methods of managing hostapd.
# Uncomment and set DAEMON_CONF to the absolute path of a hostapd configuration
# file and hostapd will be started during system boot. An example configuration
# file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz

# Additional daemon options to be appended to hostapd command:-
# -d show more debug messages (-dd for even more)
# -K include key data in debug messages
# -t include timestamps in some debug messages
# Note that -B (daemon mode) and -P (pidfile) options are automatically
# configured by the init.d script and must not be added to DAEMON_OPTS.

6). Reboot the Pi

Reboot the Pi to apply the interfaces config, start the hostapd daemon, start dnsmasq daemon. After the reboot you should see your new wireless SSID being broadcast and you should be able to login to it too with your provided password. At this point we need to proceed with the IP tables configuration to setup routing and PAT (port address translation).

7). Enable NAT and Routing Non-Persistently

Execute the following commands to enable NAT and routing for this particular session (we will make these settings persistent across reboots in steps 9 and 10).

#Enable Routing
sudo sysctl -w net.ipv4.ip_forward=1

#Apply the NAT/PAT config 
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Routing allows the Pi to move (or “route”) packets between the two interfaces (Wlan0 and Eth0). Making the Pi a Router allows packets which come in on the Wlan interfaces to be forwarded through the Pi and out the Eth0 port.

NAT stands for Network Address Translation. In this case we’re technically performing PAT or Port Address Translation because we are aggregating the connections and streams of multiple downstream/client IP addresses across a single public IP address using different source ports. As a result packets will be re-written as they pass through a NAT router to be sourced from the public IP address of the NAT router. This re-write hides the original source IP address of the client which generated the traffic. In order to keep track of which stream should be returned to which client, the NAT router keeps a table that maps the Egress destination port to an client IP and source port. This table is called a NAT translation table. You can view the content of the Translation table at any time with the following command:

cat /proc/net/ip_conntrack

8). IP Tables Configuration:

IPtables is a program which interacts with the networking stack in the Linux kernel and tells the kernel how to handle incoming network traffic. There are all kinds of customizations that can be made to an internet facing router. What I show below are pretty basic and generally recognized as safe defaults.

Apply the default config by pasting the following commands into the command line on your device:

#allow incoming traffic from the localhost
sudo iptables -A INPUT -i lo -j ACCEPT
#explicitly allow all icmp/ping traffic
sudo iptables -A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
#explicitly allow all traffic that is already established
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#Allow new traffic only from the local/WLAN network
sudo iptables -A INPUT -i wlan0 -m state --state NEW -j ACCEPT
#Drop all other new traffic
sudo iptables -A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP<
#Drop all fragments
sudo iptables -A INPUT -f -j DROP 
# Drop XMAS packets
sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# Drop NULL packets
sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
#allow our dns traffic 
sudo iptables -A INPUT -i wlan0 -p udp -m udp --sport 53 -j ACCEPT
#log everything else that is about to get dropped. 
sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES Dropped: " --log-level 7 
#drop everything else that has made it this far down and not matched. 
sudo iptables -A INPUT -j DROP

You can see the presently applied iptables rules using the “iptables-save” command with sudo.

pi@raspberrypi:~ $ sudo iptables-save
# Generated by iptables-save v1.4.21 on Thu Dec 24 17:37:34 2015
:PREROUTING ACCEPT [7039:855804]
:INPUT ACCEPT [1138:80267]
:OUTPUT ACCEPT [1167:81793]
# Completed on Thu Dec 24 17:37:34 2015
# Generated by iptables-save v1.4.21 on Thu Dec 24 17:37:34 2015
:FORWARD ACCEPT [444346:360889024]
:OUTPUT ACCEPT [4390:510099]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A INPUT -i wlan0 -m state --state NEW -j ACCEPT
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A INPUT -i wlan0 -p udp -m udp --sport 53 -j ACCEPT
-A INPUT -j LOG --log-prefix "IPTABLES Dropped: " --log-level 7
# Completed on Thu Dec 24 17:37:34 2015

Once you’ve setup the rules you’d like, and you’ve tested that they behave as expected, proceed to step 8 to save the IP tables rules.

9). Make the IPtables Settings Persistent

During the installation of the iptables-persistent program it will ask you if you want to save the presently applied rules, select YES.

sudo apt-get install iptables-persistent -y

Once the rules are saved, they can be edited at the /etc/iptables/rules.v4 (for normal IPv4 traffic). If you’re testing your iptables changes by applying the rules directly using the iptables syntax in step 7 then as you make changes, they can be made persistent by writing the output of the “iptables-save” command directly to the rules.v4 file like so.

sudo iptables-save > /etc/iptables/rules.v4

10). Enable Routing Persistently

The following change allows the Raspi Router to move packets from one interface (wlan0) to another (eth0) by making the device a router.

sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf

Halloween Home Automation

Now that my son is 13 months old I finally had  at least a moment or two to work on a Halloween display so naturally I wanted to get some automation activities integrated with my platform of choice, the Raspberry Pi.

Note: My code is available at the bottom of the project.

My goal for this project was to use every trick I could with a minimal budget to scare as many neighborhood kids as I could. Mission Accomplished.

Here was the rough order of operations.

  1. Motion sensor runs in a loop looking for motion.
  2. When motion is detected start the smoke machine smoking immediately and run for all additional events in the list.
  3. Wait for a moment or two then cut all of the exterior property lighting.
  4. Wait for another moment then play one of the spooky sounds from the hidden speakers in the bushes very loudly.
  5. Revive the property lighting.
  6. Wait 15 seconds then repeat.

Controlling the Smoke Machine

The first order of business was to reverse engineer how the smoke machine remote actually works. Two years ago I had purchased the biggest non-commercial smoke machine I could find as part of my annual Halloween budget. That first year I just used the included remote but even then I knew I would eventually have to figure out how to automate the smoking functionality. I know they also sell remotes that don’t have the simple on/off button like mine has; instead you can pay $16.99 for a remote with an interval smoking function from a store like Spirit Halloween– but again, I didn’t want an interval– smoke juice is expensive I want to use it only when a person is actually nearby to enjoy it. So this led me down the path of figuring out how to control it.

Using a standard multimeter set to measure resistance I determined what each of the 3 pins in the remote did and determined that in order to produce smoke I needed simply to bridge two of them. This is the enterance-point for my 4-way relay I had purchased a year ago for just such a task.


Hooking up the relay to bridge the necessary pins I was able to produce smoke — SUCCESS! Now to set this up a little more permanently, as it turns out the remote is actually switching 120v wall power so extra care is needed when wiring this up to do it right. I obtained some extra lumber I had from another project and started building a control board that everything would be permanently affixed to.

Breadboarding with 120v

At this point, I’ve used a combination of drilling and ziptieing to secure the raspberry pi (with case), breadboard, and relay bank to the control board which was a sheet of 1/4 inch MDF.

Adding Motion Sensing

The next phase was to setup the smoke machine to fire when motion was detected. To accomplish this I used a cheap PIR sensor that I had purchased off of E-bay last year for about $3.00 via the direct from China route.

It took a bit of adjusting on the PIR sensor to get it setup correctly for my application. In this case there are two adjustments, one is sensitivity, and the other is time-delay (how long the signal wire stays high when motion is detected). For this project I essentially set the PIR sensor to maximum sensitivity and the shortest time delay for a hair-trigger. I wanted to maximize the granularity of the sensor and push the false positive detection into software where I could control it with variables in a program instead of by turning physical knobs.

Once configured I did a bit of trial and error by moving back and forth in front of the sensor in my garage. My neighbors would probably have thought me crazy moving back and forth in my garage for 15 minutes but they know better by now. I found that the effective range of the sensor was about 15 feet.

Now that I had the sensor working with some test code (included it was time to setup some spooky noises to be triggered with the motion sensing.

Setting up the Audio

I wanted to use the included headphone jack on the Pi to play audio into a little class T amplifier (I swear this used to cost just under $20 when I bought it, it has AMAZING PERFORMANCE for the price) and an old pair of extra speakers that had been collecting dust around my workshop.


As it turns out there was an issue with some of the updates I had performed most recently on my Pi that left my audio broken, after a bit of soul-searching on google for the error message I saw when trying to use Aplay to play a sample audio file I decided to do some updates and see if that would solve the issue.

sudo apt-get update -y && sudo apt-get upgrade -y

Sure-enough my audio was now working with Aplay after the dust cleared from the updates and a reboot was performed.

At this point I began searching the net and collecting spooky noises from various sound effect websites. I collected all ten of the wav files which made the final cut and renamed them from 1-10 (My code actually randomly generates an integer from 1-10 and plays the corresponding file 1.wav – 10.wav for simplicity).

Adding The Exterior Lighting Control

Since the majority of my exterior property lighting is already wired for automation with WEMOs I wanted to include this in my Halloween setup. I bought 3 red LED bulbs and went to town replacing the exterior lights with an eerie red glow. They actually created a lovely scary effect. The bulbs were certainly not cheap though.

Regarding the code for the WEMOs, I already had this code built from various WEMO projects but I wanted to do something very simple for this project, just an on/off, no database tracking, no fancy behaviors, no logging etc. so I re-wrote some of the code to run a little faster and added a little pair of bash scripts ( and to bring up multiple switches in rapid succession, the effect is truly instant when kicked off in this manner so I was very happy.

Carving the Monster Pumpkin

I’ll have to add a picture of the beast when it was all carved but I picked up a gigantic pumpkin from the Raleigh State Farmer’s Market for $50. I’ve always wanted a pumpkin this big. I figured with this no one would be able to doubt my Halloween spirit. This pumpkin was so large that it took two grown men to move it on a towel. I honestly could not lift it myself which was very emasculating but also thrilling that it was so incredibly huge.


I know I have a carved picture of it somewhere but I can’t seem to find it at the moment so I’ll post that bit later. These super huge pumpkins are actually a different species and produce really nasty seeds that you can’t cook up which is an interesting fact I learned when I opened this bad-boy up.

When the scary face was all carved I then carved a 3inch diameter hole in the back for the dryer hose…. dryer hose you ask?  Of course you need dryer hose when you’re…

Building the Fog Chiller

One of my favorite pieces of Halloween tech is a good fog chiller. When you cool the fog down to a temperature that is lower than the outside air it will actually sink down to the ground and drift along making an extra scary effect. This was a trick I masterminded when I was organizing the annual public Haunted House in my fraternity days. The effect is great and luckily I had an old 50 gallon plastic drum that I had purchased off of Craigslist several years ago that was a perfect fit for the project.


Essentially you cut a hole in your container, coil the dryer-hose around within the container then run the hose to your destination which in my case was the back of the gigantic pumpkin. I also added a string of green LED lights in the pumpkin as well to give the fog a cool effect.

Lastly you fill the container with a combination of ice and water. I actually began saving up ice from my refrigerator and storing it in my chest freezer several weeks in advance in order to be able to fill up the drum and not spend any direct dollars from the Halloween budget on frivolous things like store-bought ice.

Putting All the Pieces Together With Code

Now that all the individual pieces were functional all that was left to do was to write the code to unify the individual pieces and create the coordinated show.

This code can be found in the file.



The effect was awesome! Many neighborhood kids and parents were scared some wouldn’t even set foot on the property which is a personal win because that means more candy for me and as an adult lets be honest, there are few joys in life like making kids you’ve never met cry. I will probably grow this by adding motion activated lawn effects next year but this year was a total success!

Get the Code

I’ve posted my code from the endeavor to my github page in a new Halloween 2015 repo:

Amazon Dash Button Automation


If you haven’t heard about them, Amazon is putting out these shiny new buttons which are basically walking advertisements for certain brands of products. You can stick them to a wall with the included adhesive or hang them somewhere with the included ring (not pictured). What is even more interesting is that when you press one of these buttons they are supposed to place an order for a new product without any interaction on your part. They connect up to your home WIFI (with a bit of initial setup through the Amazon app) and beam the order request out to Amazon on the double so you can have your new garbage bags in a jiffy.

They come in veritable cornucopia of flavors right now, 18 buttons in all at the time of this writing. With multiple different companies vying for the opportunity to pitch their wares to you and get a little ad-space on your wall. Rumor has it that these companies are even paying Amazon for the privilege of being button-ized.


Amazon is pitching these things for $5 a piece right now to Amazon Prime members only. Although supposedly you’ll get a $5 discount when you place your first order of product X using the button. You’ve really got to hand it to Amazon here, they’re making money on both ends, from the business AND the user. Let’s forget the fact that the whole concept is just a bit ridiculous (even for a technophile like me)… that they’d expect you to pay $5 for the convenience of hitting a button to order a product. That you would be so lazy as to not even perform the most rudimentary of price comparisons. That you would be willing to pay the iron price Amazon price for whatever good… whatever it happens to be. Are we all really that lazy busy?

Poor product ideas aside, I immediately plopped down $10 in Amazon gift card money and bought two of them right before my Prime subscription ran up because something tells me these aren’t going to be on the market for very long. After being inspired by Ted Benson I had a feeling there must be something I could set these up for.


I purchased the most basic dash button model I could find with the least offensive advertisements… in this case this was the Amazon Elements model. When they arrived I immediately covered up the amazon logos with a label maker and called the buttons, very memorably, #1 and #2.

Here you can see the hanging rings included with the buttons, the button on the right is naked.

Setup of the buttons is really simple but you must be careful to NOT COMPLETE THE SETUP. You wouldn’t want these buttons to actually order something hahaha. If you accidentally do complete the setup (like I did), you can dissociate the button from whatever product you picked but I recall it being an extra annoying step. Read the Ted Benson article here for clues on where to abort the setup process. For me it was as simple as force-closing the app on my phone when it prompted me to select the radio-button for a corresponding product. Presto chango the button was now rendered useless. It will still connect to your home Wifi and communicate to Amazon but it will not complete the ordering process.

Actually if you were to stop right here things would be quite annoying for you because every time you hit the button it still communicates with Amazon and then the silly phone app blows-off an annoying message to you reminding you to finish setting up your button. This gets old really quickly even when I was testing– even more fun is that the notifications stack up in Android so you’d have a list a mile long of notifications unless you take the next steps.

1). Setup a static IP for the button

2). Block all traffic from that IP out to the internet

You can use “discover mode” shown in python code below to learn which MAC address your dash button has in order to properly bind it to a static IP. Regarding the ability to block traffic, not every home Wifi router can support this function but if you have a newer router like the super-awesome Asus RT-AC68U you’re good to go. In my case I built a rule that applied to all hours of every day and applied that to the IP addresses of the two buttons for all of both kinds of traffic, TCP and UDP. Basically these things are now entirely disconnected from the internet.


Sure enough, when I applied these rules and continued pressing these buttons, I no longer received any notifications from Amazon. One side effect of this action is that the buttons stay awake longer as they try (and fail) to communicate with Amazon; I would estimate about 30 seconds in total although I have not specifically timed it.

Onto the fun stuff.

Now that the buttons are setup I cannibalized and re-factored some code to listen for them on the network. Here is what I ended up with.


import sys
import time
import socket
import struct
import logging
import binascii
import subprocess

                    format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S -- ')


if len(sys.argv) > 1:
    if sys.argv[1] == "discover": discover_mode=True

rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))
    "00bb3aff6aea_192.168.1.00":["Button One",0,["/home/pi/scripts/WEMO/","sendall.toggle"]],
    "747548bd4908_192.168.1.255":["Button Two",0,["/home/pi/scripts/WEMO/","kitchensink.toggle"]]}' ### Dash Button Service Started ### ')
while True:
    packet = rawSocket.recvfrom(2048)
    ethernet_header = packet[0][0:14]
    ethernet_detailed = struct.unpack('!6s6s2s', ethernet_header)
    arp_header = packet[0][14:42]
    arp_detailed = struct.unpack('2s2s1s1s2s6s4s6s4s', arp_header)
    # skip non-ARP packets
    ethertype = ethernet_detailed[2]
    if ethertype != '\x08\x06': continue
    source_mac = binascii.hexlify(arp_detailed[5])
    dest_ip = socket.inet_ntoa(arp_detailed[8])

    if discover_mode:"We saw an arp from MAC: " + str(source_mac) + " ip: " + str(dest_ip)+ "\n")

    if identifier in buttons:
        buttons[identifier][1] += 1 #iterate the count of button presses[identifier][0] + " Pressed " + str(buttons[identifier][1]) + " times.\n")

Or download the code from my Github Gist page.

The code has two modes in which it can be run:

  • Discover mode: ./ discover
  • Vanilla mode: ./

In discover mode the script will call out whatever MAC addresses it sees sourcing ARP packets… Press your button here and see what addresses your button owns. Once you’ve defined the static IPs in your router come back to the script and update the buttons dictionary with your “tuple” of MAC and IP address followed by your colloquial name for the button, the number of times it’s been pressed and lastly the command that should be executed by subprocess when the button is pressed.

Now you can run the script in vanilla mode to test pressing your button.

A simple few lines of code which sniff all incoming traffic listening for ARPs from a specific tuple of source MAC and IP address. Since this script is essentially sniffing all incoming packets you’ll want to situate this code on a remote part of your network that doesn’t process big file transfers or the like. In my case I have this code sitting on a Raspberry Pi that isn’t used for much.

Reading the code, you can see the “tuple” as the key for the “buttons” dictionary this is the key to identifying traffic we care about. The format for the buttons dictionary is rudimentary but functional and avoids making a class for something really simple.

In my example I’m kicking off WEMO Events whenever buttons are pressed. I keep button #2 by my nightstand and press it to turn off my kitchen light when I go to bed. Button #1 just toggles every light switch in the house for fun.

Starting the Script on Boot:

I built an Upstart job to start the script at each boot. In order to use this method, you’ll need to install Upstart on your Pi with:

pi@pi ~ $ sudo apt-get install upstart
Reading package lists... Done
Building dependency tree 
Reading state information... Done
Suggested packages:
The following packages will be REMOVED:
The following NEW packages will be installed:
WARNING: The following essential packages will be removed.
This should NOT be done unless you know exactly what you are doing!
0 upgraded, 1 newly installed, 1 to remove and 81 not upgraded.
Need to get 502 kB of archives.
After this operation, 940 kB of additional disk space will be used.
You are about to do something potentially harmful.
To continue type in the phrase 'Yes, do as I say!'
 ?] Yes, do as I say!
Get:1 wheezy/main upstart armhf 1.6.1-1 [502 kB]

You can see during the Upstart install the system actually prompts you for such a big change with some special language [bolded above].

After Upstart is installed give your Pi a reboot:

sudo reboot

Lastly build the Upstart job by creating a file called “/etc/init/dashbutton.conf” and adding the following contents [replacing the exec line with the location where you have stored the script on your machine]:

author "Eric Pulvino --"
description "Upstart Script to run Amazon Dash Button service"

start on runlevel [2345]
stop on runlevel [016]


exec /home/pi/scripts/

That’s it. You can reboot your Pi to automatically start the service now however you could also just run the following command to start the service manually:

sudo service dashbutton start


I’m sure there will be more in store for the buttons down the road with Halloween so close by. My typical Halloween goal is to literally scare the neighborhood children (and adults to death) so I might setup the use of the buttons to disable some of the really scary effects for 30-60 seconds when I see little children coming up the walk. Either way I’ll be sure to post some of my Halloween antics this year!

Raspberry Pi WeMo Home Automation Control Center

WeMo PlugFor the last year I’ve had a Raspberry Pi that is always on mounted underneath my house. I power this device using PoE (Power over Ethernet) so there is literally a single ethernet cable that provides it with the ability to run for simplicity’s sake. This unit was the first Pi I had ever purchased so I’m a little nostalgic about it until you consider that I make it live in a crawlspace under my home.

While it is sitting under the house it’s performing a few vital services for me.

Service 1: Property Temperature Monitoring — Perhaps someday I’ll do a write up on this aspect.

Service 2: Amazon Dash Button Receiver

Service 3: Home Automation Control Center 

I have been meaning to write an article on Service 3 for some time. Of course I didn’t actually get around to doing it until there was a contest involved because it is a well known fact that I will do unspeakable things for free t-shirts. The write up on my Raspberry Pi Home Automation Control Center can be found on

Hydrogen Peroxide Mouthwash on the Cheap

The cost of mouthwash is too damn high. Jimmy McMillan may not have said those exact words, but he might as well have. The cost of two 32oz. bottles of Crest 3D White mouthwash (if you can tell me what is 3D about mouthwash you get a prize) is a few cents short of $10.00 at Sam’s Club as of this writing.  About a year ago I said enough with this nonsense and started making my own and haven’t looked back.

Hydrogen Peroxide Facts

Why do I bother?
1) Price

This stuff is basically hydrogen peroxide and some potentially carcinogenic sweeteners in a pretty bottle. I think I can get a similar result for way less.

2) Flavor

Have you ever seen a bottle of cinnamon mouthwash? Me neither — don’t let the man tell you what flavors to cleanse your mouth with. Personally I’m a spearmint man but almost all mouthwashes seem to be peppermint flavored. Mine is no different though; my wife hates cinnamon and prefers peppermint to spearmint, so guess which flavor of mouthwash I make — correct — peppermint. Someday I will taste the rainbow of other flavors… but not today.

3) Health

In a recent NIH study, hydrogen peroxide “markedly reduced the amount of plaque formed and significantly retarded gingivitis development.

Ingredients in my Crest 3D Mouthwash.


Here are a few of the ingredients that you’re avoiding by making your own H2O2 Mouthwash…

4) Simplicity

Easy ingredients you may already have around or a few clicks away on Amazon. As a matter of fact, the back of your hydrogen peroxide bottle already mentions use as a mouthwash. Here’s mine:

The back of my H2O2 bottle.

What You’ll Need:

I like to add my flavoring to the hydrogen peroxide first and then add the sweetener to make sure I get just the right flavor. For me that comes out to about 11 drops of flavor and about 1 tsp of stevia for an EXTRA punchy peppermint that is not overly sweet.

Give it a shot and leave your suggestions for other flavors or modifications in the comments. I’m sure I’ll continue to tinker with this recipe in the future.





Raspberry Pi Nursery Cam

One of my most recent projects has centered on the new IMG_20150104_005102addition in my family. With the baby on the way I started looking at baby monitors and realizing that a simple little video-enabled baby monitor was around $300. I figured I could do much better than a tiny 2″ screen and integrate some useful features along the way.

Goal: Sub $300 Baby Monitor Camera

Result: $100 Nightvision Camera /w FM Audio Broadcast


  • Full 1080p Streaming (cropped image) over Ethernet (Full Frame Image /w 1296×972 resolution)
  • Internet Streaming capabilities to broadcast video to Computers, Phones and HTPCs.
  • Selectable FM Frequency for Audio Transmission – any radio in the house is now a baby monitor including bedside clock radios.
  • Separate Audio and Video Transmission for all different kinds of endpoints
  • Full Nightvision capabilities with the PiNoir Camera Module and IR LED module (can be used in total darkness and picture is excellent)
  • IR LED module shuts itself off when not needed due to a built-in photoresistor
  • Authentic Camera look salvaging a dummy enclosure
  • Stream plays easily in XBMC making any HTPC double as a video receiving endpoint.

Parts list:

Dummy Camera Shell from Monoprice — $7.94
IR LED Light Array from Amazon — $5.90
Slice of Pi Breakout Board — $8.25
Cheap USB Microphone from Amazon — $7.95
Raspberry Pi Model B — ~$40
Raspberry PiNoir Camera Module — $25
Nylon Washers and Tiny Nuts/Bolts — $1.50

Misc Parts (freebies):

SD Card
Piece of Wire
Ethernet Cable
MIcro USB Cable
USB Power Brick
12vdc Power Adapter for LED’s

Project Details:

Gut The Dummy Camera Enclosure

The first order of business was to gut the innards of the dummy camera case to make room for the Pi. In my case I took my dremel cut off wheel and hollowed-out the back of the case to make room for all the wires and SD card which hangs out the back a bit. Removing all the Battery, LED components, and fake LED array left plenty of room for our frankencamera. The IR LED array is pretty much a direct fit for the fake one that was removed. I discarded the black plastic backer behind the fake LED array too. By countersinking the holes that hold the fake LED array in place I was able to reuse the mounting bracket to tighten down the new LED array as a direct replacement for the fake one.

You can see the LED array has mounting holes that line up almost perfectly with one of the pairs from the PiNoir module.
You can see the LED array has mounting holes that line up almost perfectly with one of the pairs from the PiNoir module. I used nylon washers and a pair of nylon spacers between the two boards to keep them from touching each other or anything conductive.
You could even dremel-out the battery compartment and stick a little thumb drive here for local storage of video/audio content. Since my device is a network streamer I left this compartment alone after removing all the metallic components.
Dremel out the back of the enclosure. This was only necessary for me because of my cheap USB microphone which could not bend very well in the case.
My pet black widow I caught in my workshop as I was working.
My pet black widow I caught in my workshop as I was working.

Install Software

For this project I just used the basic Raspbian image on the SD card. From there I enabled turbo-mode for on demand overclocking up to 1ghz. This project uses PiFM to broadcast audio on the FM bands. PiFM is a quick and dirty solution to acheive my goals. Be aware that PiFM is a pretty noisy transmission that has strong harmonics in bands you should not be transmitting on — that being said, your range is very small (about 30-300ft depending on the length of your antenna) and will probably not hurt anyone (use your judgement and check your local laws to make sure you’re in the clear here). Install PiFM and test that your broadcasting works. Once you’ve confirmed you’re broadcasting as expected you can use Radio Locator to determine which FM frequencies are vacant in your area. Broadcasting on a vacant frequency will give you the best performance and range. I ended up trying a few of the frequencies in the “BEST” category before I found one that was pretty much perfect for me and gave crystal clear audio. For a more permanent antenna attachment, I soldered my antenna wire to the “Slice of Pi” breakout board. I may also add a toggle switch for the FM transmission at some point so it’s nice to have the breakout board ready to go.

Configure Camera

The PiNoir camera module is actually a really capable camera and using the included raspivid software can be configured to behave however you could want it. It’s worth reading about the different modes the camera supports and making a decision as to what is most important for your application. For me I did not need a high quality 1080p stream so much as I did a wide field of view since the camera is close to the subject being filmed. For this reason I selected the 1296×972 resolution which uses the entire sensor for the widest possible field of view.

After selecting the resolution it’s time to tweak your raspivid settings to give you the best results. I after reading through all of the settings and doing a good bit of experimentation I settled on the string below:

#1296×972 1-42fps, 4:3 aspect binned full FOV.
raspivid -h 972 -w 1296 -br 46 --colfx 120:120 -o - -t 0 -vf -hf | cvlc -v stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264

You’ll notice in my code above I’m using the color effects feature to skew all the colors to a nightvision color palette. I did this because occasionally due to power fluctuations on the camera module the image would shift a bit back and forth from green to red, the effect was significant enough for my wife to notice it which means I wanted to fix it. By specifying the color effects I was able to work around the color-shifting artifacts. FYI the color shift is due to the poor design of the Raspberry Pi power supply circuitry; I believe this may no longer be an issue with the enhancements made to the newest B+ model but since I don’t own one, I can’t say.

Create a Streaming File for XBMC/Kodi

If you want to play your stream on an XBMC/Kodi machine you can put the details of your stream into a simple text file and Kodi will play your stream when you play the file. Here’s my example file that I used.

Filename: Baby.strm

rtsp://[IP Address of PI]:8554

Startup Scripts

A bit of scripting will allow the video and audio to start when the machine boots. My startup scripts are provided below.

/etc/init.d/SCREEN_STARTUP — quick script that starts both Audio and Video streaming at boot time. Don’t forget to add it to your startup with “sudo update-rc.d SCREEN_STARTUP defaults”.


#Raspberry Pi actually doesn't actually support MTU over 1500
#   but does not bark when you set it. See Link below:
#ifconfig eth0 mtu 9198

/usr/bin/screen -d -m -S "RASPIVID SESSION" /home/pi/raspivid_abstraction &

sleep 2 

/usr/bin/screen -d -m -S "PIFM SESSION" /home/pi/pifm_stream_command &

echo "Script has attempted to start both screens"

sleep 1
echo "List of available screens is:"

screen -list

/home/pi/ &


/home/pi/raspivid_abstraction — necessary to run VLC under the Pi user, VLC will not run as root without modification.


su - pi -c "/home/pi/raspivid_stream_command"

/home/pi/raspivid_stream_command — starts the video stream (just uncomment whatever mode you want to use)

#1296×972 1-42fps, video mode, 4:3 aspect binned full FOV.
raspivid -h 972 -w 1296 -br 46 --colfx 120:120 -o - -t 0 -vf -hf | cvlc -v stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264

#Experimental adding sound -- does not work! Raspivid sends raw H264 Stream, would need to have an intermediary step with Gstreamer adding the timing information to the video stream in order to layer the audio on top of it.
#raspivid -h 972 -w 1296 -br 46 --colfx 120:120 -o - -t 0 -vf -hf | cvlc -v stream:///dev/stdin --input-slave=alsa://plughw:1,0 --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264

#1296×730 1-49fps, video mode, 16:9 aspect , binned, full FOV (width), used for 720p
#raspivid -h 730 -w 1296 -br 40 --colfx 120:120 -o - -t 0 -vf -hf | cvlc -v stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264

#1920×1080 1-30fps, video mode, 1080p30 cropped
#raspivid -h 1080 -w 1920 -br 40 --colfx 120:120 -o - -t 0 -vf -hf | cvlc -v stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264

/home/pi/pifm_stream_command — Starts PiFM

arecord -fS16_LE -r 22050 -Dplughw:1,0 - |  /home/pi/software/pifm - 106.7 22050

/home/pi/ — Makes sure that both commands are still running, I’ve found PiFM occasionally dies out, so this script restarts it.


while true; do
    sleep 30
    PIFM=$(screen -list | grep PIFM | wc -l)
    RASPIVID=$(screen -list | grep RASPIVID | wc -l)
    if [ "$PIFM" -ne "1" ]
        /usr/bin/screen -d -m -S "PIFM SESSION" /home/pi/pifm_stream_command &
        echo " $(date) -- PIFM restarted." >> /var/log/screen_watcher.log
    #    echo "PIFM still running"

    if [ "$RASPIVID" -ne "1" ]
        /usr/bin/screen -d -m -S "RASPIVID SESSION" /home/pi/raspivid_abstraction &
        echo " $(date) -- RASPIVID restarted." >> /var/log/screen_watcher.log
    #    echo "RASPIVID still running"

Ideas for Future Enhancements

  • A button to toggle the FM transmission on/off
  • Eventually I’ll do a similar build (minus the audio) for an exterior surveillance system. Monoprice sells actual camera enclosures for this purpose

Final Tests

Two sided tape was applied to the bottom of the microphone to stick it to the wall. I used the included hardware to mount the bracket as well.
Two sided tape was applied to the bottom of the microphone to stick it to the wall. I used the included hardware to mount the bracket as well.
The baby actually looks a bit creepy here but the picture quality is awesome on this old 25" monitor I had laying around. I purchased a flat screen TV wall mount for my Bedroom Media Center project.
The baby actually looks a bit creepy here; I think he is hypnotized by the faint red glow of the IR LEDs but the picture quality is awesome on this old 25″ monitor I had laying around. I purchased a flat screen TV wall mount for my Bedroom Media Center project which is what I’m using to view the video stream here.
The XBMC Bedroom Media Center playing the stream.
The XBMC Bedroom Media Center playing the stream.

Everything works like a charm. There is about a 6 second delay for both the audio and video transmission which does not really bother me for my application. In my brief research on the subject I think I read it was due to the buffering. One of the things I really like about this project is the separation of the audio and video transmission so you don’t have to have the whole media center on to listen to the audio. You can just use a bedside clock radio (not pictured) to listen to the stream.