Introduction: IOToilet

About: a hacker and a maker of potentially anything I can get my hands on. dad. aspiring Inventor. educator. hacking life, one bit at a time.

The IOToilet is the first smart toilet paper holder, that keeps track of our daily usage of toilet paper and allows accumulating stats showing these metrics. And why should I care about my daily usage of toilet paper you may ask? Well, as it turns out, our abdominal health, especially the digestion cycle, has a lot to do with both our physical health and our mental one. For example, here's a nice TED talk (one of quite a few, by the way) that elaborates on this subject:

I was initially commissioned to build 10 units of this device for a branding agency, whose clip you can see above (2nd location), for a purposed marketing campaign for a large company. At the beginning, I dismissed the idea as one coming from an another over-creative mind desperately trying to win a client account, but gradually it grew on me, until I realized the value of the information collected through this device.

The build was based on an existing piece of hardware my client got from EBay, a voice recording device encapsulated in a toilet paper holder. It had the right form factor and all the needed peripherals already built in, such as a speaker, a movement sensor to trigger the device, springs to hold the toilet paper itself, battery compartment, and an on-off switch, so I gladly opted using this ready made rather than modeling and printing my own.

Step 1: Tools and Materials

Materials used:

Toilet paper holder

Wemos D1 Mini

ATTiny85 chip, DIP packaging

2 x 2n2222 transistor

220 Ohm resistor

2 * 1KOhm resistor

MPU6050 accelerometer

Optional, in case not using my PCB:

Wemos prototyping shield

wire, solder, etc.

Tools used:

Dremel with a cutting disc

ATTiny dev board (for conveniently uploading firmware)

USB Tiny ISP programmer

triangular screwdriver, I used this kit:

Step 2: Dismentaling the Original Unit

After obtaining the original toilet paper spindle, I opened its case using a triangular screwdriver and removed the original PCB, disconnecting the speaker and leaving as much wire as possible connected to it.

I then soldered out the LED and the tilt sensor from the original PCB, to be later embedded in the new circuitry. Pay attention not to overheat the tilt switch, as it might damage. Mine was grey, but since I did not take a good shot of it when removing from the original device, I had to use a photo from the net(see above), where it was green. Just a minor detail.

After opening the case and removing the electronics, I also used a Dremel to remove excess plastic that was used to hold the original PCB in place, these little plastic shelves and one out of the 4 screw pipes. You can postpone this to the assembly stage if you like, but at any case some plastic trimming will be required.

Step 3: Circuitry Explained

So, here's a little bit about the logic behind the circuit:

In order for the batteries to last a long time, I had to put both the MPU6050 accelerometer and the ESP8266 processor in the Wemos D1 Mini to sleep between activations. The first was easily done using a transistor that turned the MPU6050 on and off.

Note: I initially thought I could program it to send an interrupt signal that will wake the main processor. Alas, I could not find a way to make it happen, configuring the proper registers of the MPU6050 was a tricky task that I still don't know if possible at all...

My second option was using the tilt switch supplied with the original unit to wake the ESP. I first tied it directly to the Wemos RESET pin as described in the photos above, using a transistor to activate/deactivate the mechanism. When the transistor base was high, the GND could pass through the tilt switch and cause it to temporarily connect to the RESET pin, causing the MCU reset (this is the only way to wake up an ESP from deep sleep, apparently). I then connected D0 to the transistor base, following the premise that this leg is HIGH as long as the MCU is sleeping, and as soon as it wakes up, D0 goes back to LOW, disabling the reset mechanism. After all, I did not need a recurring reset to happen, just for the first time when the toilet paper holder started moving.

However, what I discovered was that pin D0 takes quite a long time after MCU reset to go back to LOW, about 200ms. This meant that if I spun the toilet paper holder fast enough while the MCU was sleeping, it would get multiple RESETs occurring, instead of counting the rounds, as it should.

So, I tried solving this new situation with some discrete components (capacitors, transistors etc.) but I only managed to get partial solution to the problem.

I ended up adding another MCU, a ATTiny85, which would get awakened from sleep by the tilt switch, then, wake up the ESP8266, and wait for some time before going back to sleep. I know this is probably not the most economical solution to the problem, but I had a deadline...

You can see the detailed solution in the schema I've included. Please note that the 10K resistors were replaced with 1K as the 10k ones were too high for the transistors to get fully open.

Step 4: Preparing the ATTiny85

If you have never programmed an ATTiny85, fear not! Using the beloved Arduino IDE can get you all the way. Start with these instructions on how to configure the Arduino IDE:

Next, install the drivers for the USBTinyISP from here:

Now, load the attached test code: WakeOnExternalInterruptTest.ino

and connect (see ATTiny85 Pinout diagram):

1. Tact button between pin 3 and ground

2. An led and a 220 Ohm resistor in series, between pin 2 and ground


Select the USBTinyISP as the programmer (under Tools -> Programmer) and upload the test sketch to the board.

The LED should blink for 5 times, then the chip should go to sleep. Pressing the button will cause it to wake up and repeat that sequence.

Got it to work? great! Upload the final sketch "Awakener" to the ATTiny, to be used on the final circuit.

Step 5: Building the Wemos Shield

So, to construct the shield you have 3 options you can choose from:

1. Use a standard protoshield for the Wemos and solder the circuitry onto it.

2. Fabricate a PCB, based on the EAGLE files attached.

3. Ask me for a PCB that I can send you by snail mail (I have a few lying around, cost is next to nothing).

At any case, I recommend constructing the circuit on a breadboard before committing to the PCB!

If using the PCB options, be sure to connect the black wire as in photos, on either front or back side of the board (latter worked best for me). This wire connects the GND from the Wemos to the ATTiny85 and without it, waking up will not take place.

Just take a good look at the images and read the annotations I've added, this should be enough.

Step 6: Preparing the Wemos

If you have never used the Arduino IDE to program a Wemos board, starting by installing the board manager and selecting the board in the Tools -> Board menu, as described here:

Start by uploading the blink sketch to your board, making sure the code gets uploaded correctly.

Step 7: Putting It All Together

Install the shield onto the Wemos. You can solder it, but I recommend using female headers soldered to the Wemos that will allow temporary connection between the Wemos and the shield, in case of any trouble. Just bear in mind that the female header will have to get off in the final stage of assembly for the unit to fit into the plastic shell. Also, to make things a bit more complicated, there is a good chance that when shield is connected to the Wemos, code upload will be disabled. I've encountered that phenomenon in a non consistent way, and had no time to research it.

Word of advice: plan ahead.

Now, Testing!

Once installed, start by uploading the BlinkAccelerometer test sketch to the Wemos, and make sure it turns the MPU6050 LED on and off. If not, check the wiring of the transistor that is responsible for powering the MPU6050. Its base should be connected to pin D5 of the Wemos, the collector should be connected to the GND of the accelerometer and the Emitter should be connected to common GND.

Next, upload the TurnCountTest1 sketch to the Wemos board and open Serial Monitor. You should see data coming from the accelerometer presented on the monitor. If not working, check the clock and data wiring: CLK should be connected to D1 and DATA should be connected to D2.

Now, solder the tilt switch to the designated holes in the board (see annotations), making sure it is perpendicular to the rotation axis so that spinning the spindle will close and open the connection between its two leads.

Next, connect the Battery 3V input to the Wemos VCC, and its minus terminal to the Wemos GND. Make sure that turning on the switch turns the unit on. Lastly, connect the speaker to GND and pin D4 of the Wemos.

Upload the final code to the Wemos - a sketch called SmartWipe. Open a serial monitor and make sure that the unit goes to sleep after 3 minutes and gets awaken by moving the tilt switch (corresponding messages should appear on the monitor).

If you wish to diminish the time the Wemos is awake (mainly for testing purposes), dimish the value of WIFI_CONFIGURATION_IDLE_TIMEOUT defined in params.h and upload the sketch to the board. Make sure that after the Wemos goes to deep sleep, moving the tilt switch causes the ATTiny to wake up (signaled by the LED), which, in turn, wakes up the Wemos.

Change the value of the parameter back to 180000L (3 minutes, in millisecs) and make sure the Wemos fires up a Hotspot called IOToilet_XXXXXXXX where XXXXXXX will be retrieved from the MAC address of the chip. Connect to this Wifi using a smart phone, and you should be directed to a registration form (a mechanism called Captive Portal). Fill in the details, especially important is your local wifi's SSID and password, and submit the form. The unit should then try to connect to the network using the supplied credentials, and if successful, play 3 ascending sounds on the speaker. If there had been a problem in connecting to the Wifi, 3 descending sound will be played. After that, the Wemos should go to deep sleep, until awakened by movement.

Finally: End to end System test.

Roll the toilet paper holder along its rotation axis a few spins, then place it on a steady surface (to signal using the roll has ended and trigger data upload). Wait about 10 seconds for the roll count to be sent to the cloud, then go to and click Query. You should see your registration details and your recent usage roll count in the cloud! Be sure to write down your uuid, which is your unique id in the system, extracted from your Wemos's MAC address.

If you wish to extract only your stats in JSON format, use a URL similar to this:

just replace uuid with yours.

I've included all sources for the web app, which is hosted on Google App engine so that users who wish to gain more privacy to the data, can deploy it on their own Google user, add authentication etc.

When everything is working, fit the electronics into the plastic shell, trimming plastic with a dremel as needed. The entire piece should nicely fit into the housing.

Trouble? Write me!



Wireless Contest

Participated in the
Wireless Contest