Introduction: Arduino Compatible Bathtub Controller

Lets start with a warning: this project controls water. Electricity and water really don't mix and there is a real risk of electrocution and or death if you are not careful. Build this project at your own risk and I won't be held responsible for anyone who builds this. make sure you use a battery to power this NOT a mains transformer of any kind. just be smart and be safe.

Any and all damages/injury incurred by the implementation of the information in this publication are the sole responsibility of the end user, I cannot accept any responsibility.

What is this? it is a arduino compatible (ATMEL 328p) based home bathtub controller.

this controller sets the depth, adds bubbles and monitors the temperature of a bathtub based on a user profile. v2.5 has support for Internet of things but it is not fully implemented.

But why? Well why not? ever wanted to have a bath ready at a touch of a button or from your smartphone(coming soon)?

Well now you can.

Basically this is an arduino compatible board that switches 3 relays, monitors the inlet temp with a DS18b20, the tub temp with a second arduino compatible board remotely via 434mhz and adds bubble bath via a hacked automatic soap dispenser. Version 2.5 will have wiznet Ethernet support.

This project was at Maker Faire NC 2013 & 2014 and was a hit.

Here is a video from Maker Faire NC 2013 where we had a full size demo going:

this is also my 1st instructable.

Step 1: Bill of Materials

Main Board:

Parts are all through hole

• 1x 328p Atmega with arduino bootloader
1x DS18B20 I used one like this:
1x 434mhz receiver:
2x 10k resistor
2x 100ohm resistor
3x 2.2k resistor
1x 4.7k resistor
3x 1n4001 Diode (watch polarity)
3x n2222 transistors
1x 5mm led (I used white but any colour will do) - Optional power led
4x 0.1uf capacitors
1x 1000uf capacitor (watch polarity)
1x Power socket 2.1mm
1x 16mhz resonator:
3x 5v relays (only 2 used at this time)
1x LM7805 5v regulator with heatsink
1x Buzzer:

lots of 0.1inch Break Away Headers

a few 0.1inch female headers
Custom PCB (see files)
1x 12v fill valve, if using a pump extra precautions should be used.* I used something similar to this:


resistors and capacitors are SMD805!!

• 1x 328p Atmega with arduino bootloader
1x 434mhz transmitter:
• 5x 10k resistor SMD805
• 4x 0.1uf capacitor
2x BC547
• 1x 16mhz resonator:
1x Custom PCB
1x Duck Enclousure Duckymeter:

a few 0.1inch female headers

Other Parts:

• 12v Sealed Lead Acid battery

FTDI programmer I used this one:

1x Lysol No-Touch Automatic Hand Soap Dispenser:
crimp connections for the battery terminals and pumps

• In-line fuse I put a 5 amp fuse in mine.
• 2.1mm barrel jack
Dupont cables to make the wires:
An Adafruit i2c lcd shield with buttons:
3x waterproof push buttons:
Enclosure (I have included the laser cut files but please note it is NOT waterproof)
OPTIONAL: Arduino Ethernet Sheild
OPTIONAL: Flowmeter:

NOTE: pcb and code is OK now!
The PCB traces are not thick enough to handle a pump, so you will need to add extra wire to make sure it is ok.

Step 2: The Main Controller


  1. Atmel 328p with FTDI headers
  2. 3 relay outputs (Fill Valve/Pump, Soap Dispenser, Drain Valve/Pump)
  3. Adafruit Screen shield (i2c)
  4. 434mhz Receiver for the remote in tub temp
  5. 1-wire bus for ds18b20 temp sensor to monitor inlet temp
  6. plugs for Ethernet and flow meter (v2.5 not yet implemented)
  7. Can drive 12v valves directly
  8. Laser Cut Enclosure
  9. Custom PCB

This is the main controller for this project.

It allows you to select a profile and start the bath running.

while it is running you can see both the inlet and the tub temps along with the time to completion.

once the bath is ready it will beep to let you know, there is also a low temp auto shutoff.

Step 3: The Duck


1. Atmel 328p with FTDI headers
2. 434mhz Transmitter for the remote in tub temp using off the shelf duck
3. Automatic water sensing to save batteries (version 2.5 not yet implemented)
4. Water tight, uses aaa batteries
5. Custom PCB

Basically you want to remove the internals from the duck, connect up the temp sensor and water sensors to the custom PCB and then seal it all back up again.

the duck is the remote temp sensor for inside the bathtub. it transmits the temp every second back to the main unit.

please note the current code does not have a shutoff so the batteries only last a week. this will be fixed in v2.5

Step 4: Hack the Soap Dispenser

So this was one of the easiest but coolest parts of the project.

I needed a way to dispense soap, but I didn't want to build it all from the ground up, so I bought one of these cheap dispensers:

the way it works is a phototransistor and an IR led. when the beam is broken by your hand it dispenses soap.

What I needed to do next was simulate the hand moving. the best solution was to simply control the IR led with a relay (noting that it only dispensed one qty of soap per trigger and didn't reset until it got light again).

To do this simply take it apart, find the wire that goes to the upper LED and cut one of the 2 wires. I brought that out to a connector that plugs into the main controller. Make a small hole in the back and you are done!!'

the final step is to drill a hole in the soap cartridge to allow you to use whatever soap/bubble bath you want to.

Extra Credit:

if you make a jumper for the connector you can even restore it to working the way it used to easily!

Step 5: Etch or Order the Boards

Not going to do a full tutorial here, here are 2 good ones with methods I have used before:

Photo Resist:

Toner Transfer with Laminator:

personally right now I have been using the laminator method with an HCL + Hydrogen peroxide mix. Just be careful when using these chemicals.

I have been drilling my pcb holes with a Dremel Pillar/bench-press and High speed steel drill bits.

Order boards:

I have also used this Chinese PCB maker with great results it just takes longer:

Extra Credit:

I used Grafix Rub Onz to do the silk screen layer. this made it much easier to populate the boards and it looked great too:

the other method I have used here is to use a laser cutter to etch the top side of the PCB. this worked well but alignment was tricky.

Step 6: Populate the Boards

Populate the boards using the BOM as shown.

the images show the home made board and the professionally made one.

As usual start with the smaller components 1st then work up to the largest ones.

Always use a socket for the chips and the 434mhz receiver as you will likely damage the part if you have to remove it.

Step 7: Upload Test Code

Using your FTDI and the Arduino IDE load this test sketch to the board.

It should chirp the buzzer and test each relay to make sure everything is working ok.

the Voltage regulator will need a heatsink but just double check to make sure it is not getting too hot.

The LCD should also light up as it runs its test.

You will need the following libraries:










Step 8: How to Calibrate the Fill Timer

You will need to customize the settings for your bathtub because we all displace a different amount of water (well mostly)
more info on displacement here(ironically it was discovered in a bathtub):

As we talked about displacement we need to time how long it takes to fill the tub to the correct height for each person.

for this you will need a pencil and a stopwatch or stopwatch app.

the way we do this is:

  1. fill the tub by hand
  2. get in
  3. let the water out of the tub until it is the desired depth (I like it just below the overflow)
  4. get out
  5. wait for the water to settle
  6. mark the height of the water on the side of the tub with the pencil.
  7. empty the tub
  8. time how long it takes to fill to the pencil mark
  9. convert this to seconds and enter it in the code.

    If you are setting up more than one profile if you start with the smallest person 1st you can do the height mark for each person without letting the water out.

// here are the presets for the fill timers. values given in seconds. the number for the soap is how many pumps of soap it wants
int preset1time=15; //preset 1 fill time in seconds
int preset1soap=1; //does preset 1 want soap?

Step 9: Upload the Full Code!

There will be a GitHub coming soon but until then use the attached code.

As this uses timing you need to work out how long it takes to fill the tub to the correct height for you (not to the drain when full that would waste water).

this information goes into the following variables:

// here are the presets for the fill timers. values given in seconds. the number for the soap is how many pumps of soap it wants
int preset1time=15; //preset 1 fill time in seconds
int preset1soap=1; //does preset 1 want soap?
int preset2time=30 ;//preset 2 fill time in seconds
int preset2soap=2;//does preset 2 want soap?
int preset3time=60;//preset 3 fill time in seconds
int preset3soap=3;//does preset 3 want soap?

the other part that matters is the Target and Alert temps. (my temps are in F)

float alerttemp=95.00;// this is the alert temp 95.00 for input. F
float targettemp=101.00;//this is the in tub target temp.

what the code does is monitor the inlet temp and if it goes above the alert temp then comes back down below it, it will stop filling and chirp the buzzer.

This code also uses a watchdog timer as protection against it overfilling should the code crash.

Step 10: Enclosures

You have a few options here.

  1. Laser cut wood or Acrylic
  2. Normal enclosure then drill/cut the holes.

Personally I prefer the laser cut route but not everyone has access to a laser.

I have attached a laser cut box template you can use. please note I have seen some different size LCD's so the cut outs might be a little off.

NOTE: this is going to be used near BUT NEVER IN water. So take that into consideration when choosing an enclosure type.

I chose waterproof buttons but a wood enclosure which will get damaged by the water. I am still working on a good enclosure which is more water resistant.

Step 11: Plumbing

Note do this at your own risk. Electricity and water could potentially kill you. NEVER use 110v/220v near water.

I use a 12v battery to run the device so there is much less risk of anything bad happening but know there is a risk.

In my current setup I used a 12v NC valve, 2 supply lines connected to an adapter for the aerator to the faucet.

this allows this tool to be used without removing the tub. Every install will be different so the parts will probably be different for you.

If you can remove the tub then adding the drain valve and making this so you can mix the inlet temps would be your best bet.

Parts coming soon

Step 12: Future Features: IoT Etc...

So you may have noticed the Ethernet and Flowmeter and Drain headers on the board.

these are future planned features that are not yet implemented but here was the theory behind them:


this works(sometimes)! put an Ethernet shield on those pins (need schematic) and tweak the code and you have IoT.

the issue seems to be related to a lack of Ram in the arduino and the way I have done my code. I managed to make it do its thing and it worked but it was fairly unreliable. future code releases will hopefully fix this.

Home Automation:
the plan is once this is on the Ethernet to be able to control it via Homeseer ( or any other home automation platform.


I added support for a hall effect flow meter. to be honest the timing method works perfectly well so I never felt the need to make this work but by all means give it a try.

Drain Valve:

This one is easy, the plan was to use a Normally Open valve (which means the valve is open until power is applied which is very different from the fill valve which is normally closed) on the drain. This would close when the bath was started and open again when you were done. I never implemented this as I would need access to the drain of the bath which would require tub removal which is not possible at this time.

Step 13: This Concludes the Tutorial.

This concludes the tutorial. I have been working on this project since 2011 and I am very please to share it with the world.

You can follow my other work here:

i would like to thank everyone for their support. it is a great honor to win these competitions!

Remote Control Contest

Grand Prize in the
Remote Control Contest

Home Technology Contest

First Prize in the
Home Technology Contest

Epilog Challenge VI

Participated in the
Epilog Challenge VI