Toilet Buddy is based on a Propeller Platform USB - it was inspired by Japanese toilets that play a 'Courtesy Flush' sound instead of actually flushing in order to save water. It also improves on the idea by reminding you to put the seat down and when you left the lights on.
First, I'll go over the design and show you how to make it. Then, I'll show you how Toilet Buddy can be adapted to projects that could use event-driven audio playback.
Step 1: FAQ
Toilet Buddy has two sensors - one for the light level in the room, the other for the position of the toilet seat. Based on the status of the sensors, audio samples are triggered and played through the onboard speakers;
- When the light is on and the seat is up, it plays back flushing samples
- When the light is off and the seat is up, it plays back a reminder to put the toilet seat down
- When the light is on and the seat is down, it reminds you to turn the bathroom light off
Can I use it for something else?
Yes! The ability to trigger audio samples based on external events is useful for home automation, music, R/C, and tons of different projects. After we put together the base circuit, I'll give you a few examples for re-purposing Toilet Buddy.
Will it work on my toilet?
Probably. As long as the toilet lid is taller than the reservoir tank when open, it should work;
If the lid doesn't go over the tank, Toilet Buddy won't be able to sense when it's up.
How long do the batteries last?
Over a month. Toilet Buddy spends most of its time in low power mode, consuming <1mA @ 4V.
What's the audio quality?
48KHz, 16-bit stereo, which is a little better than CD quality sound.
Step 2: Using Toilet Buddy for Other Projects
Some ideas are below, and I'll fully explore making a Grandfather Clock and an automatic doorbell after we put together the basic circuit.
Zombies can moan when people walk past or an accelerometer can be added so blades can 'swish' when swung.
Toilet Buddy could announce each hour by ringing bells, like a grandfather clock.
We can use the IR object detector to automatically alert us when people are at the front door.
Toilet Buddy plays 16-bit, 48KHz stereo samples - better than CD quality. Samples can be played based on sensor inputs, and the Propeller Platform can modify or mix the output.
R/C special effects
Enhance your R/C vehicle by playing audio samples based on the state of a servo channel
Step 3: Design
PowerMost bathrooms don't have an outlet right next to the toilet, so Toilet Buddy runs on 3xAA rechargeable batteries. It's also designed to maximize battery life by staying in low power mode until more performance is needed.
First, we'll connect the batteries straight to the 5V pin on the Propeller Platform. This skips the 5V voltage regulator, reducing standby current consumption. We also take advantage of the Ultra LDO Voltage Regulators, so we can squeeze every drop out of the batteries.
Second, we can minimize power consumption on the Propeller with our program. Toilet Buddy will sit in low power mode 99% of the time. It runs a single core when checking the sensors, and only fires up a second core during audio playback.
Keeping power consumption to a minimum will get us at least 1,000 hours on a single set of batteries, or about 40 days.
Light SensorWe use a photoresistor to measure ambient light. Its resistance changes based on how much light it's exposed to.
First, our circuit first charges up the capacitor. Then discharges it, counting how long it takes to discharge to 1.8V. The amount of time the capacitor takes to discharge is proportional to the resistance of the photoresistor. More resistance = longer discharge.
IR DetectorHere's the IR Detector circuit;
The IR LED blasts light modulating at 38kHz and the IR receiver tells us if it sees any IR light modulating at 38kHz. Any nearby objects will reflect the light from the LED, bouncing it to the receiver. Further, we can change the transmit power of the LED to get a rough idea of how far away the object is. This technique works well for short distances and when presence is more important than distance.
Speaker choice is important here, especially because we're driving the speakers directly from the Propeller's I/O pins. Using the speakers in an old pair of headphones is probably your best bet, as headphone speakers are pretty efficient. But if you want it louder, you'll need to use a pair of amplified speakers.
Now, I'll show you how to assemble the circuit. I'm going to build it on a small protoboard, but you could use a ProtoPlus or a spare breadboard - the Propeller Platform uses standard .1" spacing.
Step 4: Make It: Parts and Tools
PartsYou'll need a few parts to assemble Toilet Buddy;
- Propeller Platform USB (Adafruit, Gadget Gangster)
- ProtoPlus (Adafruit, Gadget Gangster) or any spare protoboard
- 1x 220 ohm resistors (Jameco)
- Two 47uF capacitors and one .01uF capacitor
- IR LED
- IR receiver
- One or two Small speakers
- Some spare hookup wire (Jameco)
- microSD or microSDHC card
- Ten pin headers
- Battery box or power adapter
ToolsAssembly takes about 20 minutes. If you're building it on a Protoboard, take your time with the instructions. If you've never soldered before, there are a bunch of great instructables to guide you, like this one. You'll need a few tools:
- Soldering Iron and solder. Leaded solder is easier to work with, and a 15-40 watt iron is just fine.
- Dikes. Diagonal cutters are used to trim the excess leads from components after soldering them down. I use a pair I got from Ikea for two bucks.
Step 5: Make It: Headers
Break the headers into a group of four and a group of six.
- The group of four goes at C1-C4.
- The group of six goes at C16-C21
Step 6: Make It: Wires
Step 7: Make It: Ambient Light Detector
- 220 ohm resistor at C15-C11
- .01uF capacitor at D16-E16
- Photoresistor at D12-E12
Step 8: Make It: Object Detector
LED's are polarized - one lead is shorter than the other. The short lead goes to B18 and the longer lead goes through B17. Point the LED out, as shown in the photo.
The IR receiver has 3 leads, the first lead is the leftmost when it's face up on a table. It goes at B21. The middle lead goes at B22, and the third lead goes at A22.
Step 9: Make It: Speakers
The project pack comes with a single, small speaker, although it might be too quiet for your bathroom. I strongly suggest you cannibalize an old pair of headphone and use the speakers from those - they're going to be louder.
First, solder a few inches of hookup wire to the speaker pads. Speakers are magnetic, sometimes they'll stick on to your iron while soldering. A trick to soldering speaker wires is to tape them to the table or put a small weight on them (like a spool of solder).
Take some more hookup wire and connect D20-G21. One more connection from D19-G18.
Take a look at the electrolytic capacitors - note they're polarized. The negative lead is shorter and marked on the capacitor with a stripe on the can.
For the first capacitor, the shorter (negative) lead goes at J21. The other lead goes at H21.
For the second capacitor, the shorter (negative) lead goes at J18. The other lead goes at H18.
Now, the speakers. They're not polarized. If you're using a single speaker, connect one lead at L21, the second at E17.
To add a second speaker, connect one lead at L18, the other at E14.
Finally, connect the battery box - the red lead goes at B2. The black lead goes at B4.
All done! Now we'll load up the software.
Step 10: Software
Main Loopthe main program runs through this code, checking for a reason to play a sample;
seatstatus := seatposition
lightstatus := checklight
IF (lightstatus == 1 AND seatstatus == 1)
IF (lightstatus == 0 AND seatstatus == 1)
IF (lightstatus == 3 AND seatstatus == 0)
First, it runs the method seatposition and stores the value returned in the variable seatstatus. Then it does the same thing with checklight, storing the returned value in lightstatus.
If lightstatus == 1 and seatstatus == 1, the seat is up and the light is on. Toilet buddy goes ahead and plays cover.wav. If the light is off and the seat is up, seat.wav is played.
If lightstatus == 3, that means the light timeout has been reached. Then it plays the light.wav file.
checklightThis method checks if the bathroom light is on. It uses the rctime object (part of the Propeller Tool download) to accomplish that. It charges up the capacitor connected to the photoresistor and counts how long it takes to discharge with a single line;
The variable RCValue will store the discharge time. If it's greater than the limit we set, that means not very much light is hitting the photoresistor, and we return 0. If more light is hitting it, we increment the light timer and return 1, until we reach the light timer limit.
seatpositionWe check the status of the seat with this method. We use ir object to accomplish this, which is also part of the Propeller Tool download. First, we have to tell the ir method what pins the IR LED and receiver are connected to - we do this at the beginning of the program with;
ir.init(IRAnode, IRCathode, IRSensor)
Then, when we call ir.distance, it will return the measured distance of an object in front of the sensor.
playaudioThis method actually takes care of the audio playback. It's a simplified version of rayman's wav player. First, it opens up the file we requested. Then it reads the header to see if the wav file is 44khz or 48khz. Then it starts up the wav player in a second core. Our first core then fills the audio buffer for the second core.
The important thing to keep in mind is this player will only playback 16-bit stereo wavs. Also, the headers on the wav file need to be empty so the player can find the sample rate.
Step 11: Customizing It: Grandfather Clock
First, take the original Toilet Buddy code and strip out everything except the audio player. You'll get this;
Then, we'll add in the Real-time clock object, which is part of the Propeller Tool download. When seconds and minutes are equal to zero, we'll trigger sample playback. Here's the code.
Be sure to enter the starting time in the first lines of the program. timestamp and timestamp store the minute value of the clock. timestamp and timestamp store the seconds. When minutes and seconds are both equal to 0, we know we're just starting a new hour, and it's time to make an announcement.
Why timestamp == $30 instead of timestamp == 0? Because the real-time clock object returns the ASCII version of each numeral. When timestamp is equal to $30, it's the ASCII character '0'. When an hour is passed, we trigger playback by calling the playdings method.
First, playdings figures out what hour we just entered into with; hours := ((timestamp - $30 ) * 10) + (timestamp - $30)
timestamp is the tens digit of the hours, but it's also stored as an ASCII character, so first, we subtract $30. Then, we add in the one's digit. Now, hours stores the value of our new hour.
The repeat loops through the hours, playing a middle chime sound, until the final chime should be played. Then the loop exits and chend.wav is played.
Step 12: Customizing It: Automatic Doorbell
Using Toilet Buddy to notify you when people are at the door doesn't require any changes to the circuit, just a few changes to the code.
Again, we strip out everything except the basics from our Toilet Buddy code, just like we did with the Grandfather clock;
We can remove the ambient light check - we just need to use the IR distance detector. It should be mounted / pointed around the mid point of the door. Here's the revised code;
Also, the IR sensor should be mounted near the middle of the door, pointed where the visitor would stand. Using some hookup wire makes this an easier task, as shown in the photo above.