Update 2nd Nov 2016 – Added suppression to relay contacts, added addition supply capacitor, added timeout for config.

This instructable should only be attempted by experienced constructors. It uses mains power.

This instructable shows you how retrofit a timer to your bathroom fan. With this retrofit the fan comes on with the light and then stays on for a period of time after the light is switched off. You can force the fan to turn off early by turning the light on and off quickly (on for less than 5 sec). A web page is provided for setting the period the fan will stay on for after the light is switched off. The complete user operating instructions in pdf format are here.

These instructions are also online at www.pfod.com.au

These instructions assume you already have a fan installed, operated by a separate switch. The installation of this fan timer involves removing the existing fan switch and adding some extra wiring from the light.

Update: Some times the initial design left the fan running. This only occurred in the bathroom with a compact fluorescent light. This latest update appears to have solved that problem. The update added relay contact suppression across the fan's Active and Neutral so there was no power used when the fan was off. An extra 100uF capacitor was also added to the regulator supplying the ESP8266 to help suppress supply spikes. Finally a time out was added to the config setting. The fan now turns off and reverts to normal operation after 5mins in config mode. Since it is easy to get into config mode, by flicking the light switch on and off a few (3) times, this may have been the root of the problem observed. Finally the debounce delay for AC inputs was reduced back to 10mS as users were finding the longer delay missed on/off switching. That is the users could flick the light switch faster then the debouce detected it which caused confusion.

Disclaimer – Mains Power can Kill You or Catch Fire

This project changes the use of the existing mains wiring in your house. You need to get an electrician to do these changes and you do these changes at your own risk. The hardware uses mains power and should only be attempted by experienced constructors. The hardware does not use an earth and is protected by double insulation, but it has not been certified by any standards authority and so may void your house insurance if it causes a fire. The hardware has been designed so it can be tested without using mains power. Carefully note the safety points detailed below.

Hardware and Software

The hardware is mounted in a small ABS box. The fan timer is powered by an ESP8266-01 board, programmed via Arduino IDE, which provides a captive hotspot for configuring the fan time. No internet connection is needed.

Step 1: Parts List

(Approximate prices as at Sept 2016, excluding shipping)

To program the ESP8266-01, you also need a USB to Serial cable. Here a SparkFun's USB to TTL Serial Cable (US$9.95) is used because it has nicely labelled ends and has driver support for wide range of OS's, but you can also use Adafruit's USB to TTL Serial Cable - Debug / Console Cable for Raspberry Pi which is the same price.

Step 2: Hardware Construction

The circuit for the timer is shown above and also available as a pdf.

The ESP8266-01 has very limited I/O pins available and there are a few of interesting aspects to this circuit:-

  • The optically isolated relay is driven by GPIO3 which is normally the RX line and is used as RX while programming the ESP8266-01. Once the flashed program starts to run, if DEBUG is enabled the code Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY); ensures that only the TX line is used for sending debug prints and that the RX line (GPIO3) is left free to be used as an output to drive the relay. While the ESP8266 is being programmed the relay will click as the RX line is being driven by the programmer.
  • GPIO0 and GPIO2 are used to set the startup mode for the ESP8266 (see ESP8266-01 Pin Magic). Here we need to detect the AC being applied to the 6N138 opto-isolator, but at the same time we need to ensure we can still program the ESP8266-01 and have it power up correctly after it is programmed. Following the example in ESP8266-01 Pin Magic we use GPIO0/2 as a pair. Once the program is running we make GPIO2 an output and LOW (i.e. GND) then when the 6N138 conducts it grounds GPIO0 by drawing enough current through the 3K3 pullup resistor to make the GPIO0 input LOW. When the 6N138 is not conduction the 3K3 pullup resistors ensures GPIO0 input is HIGH.
  • Why the 1N5819 diode? One problem with this arrangement is that the 6N138 is not a clean switch but rather a transistor. Although not shown in normal transistor symbols, transistors are actually made up of back to back diodes and will work (not very well) with the collect and emitter swapped over. Without the 1N5819 diode, when the GPIO0 was grounded for programming, it pulled down the GPIO2 input to about 0.9V via the 6N138 output transistor operating in the reverse direction. This prevented the ESP8266 from starting up in the correct state to be programmed. Adding the 1N5819 prevented the ground on GPIO0 from affecting GPIO2.
  • The opto-isolator, 6N138, detects the when the light is switched on. It only fires on one half of the AC sine wave. The 1N4004 diode protects it from excessive reverse voltage. The 3K3 // 100nF combination provides a low pass filter to help suppress any noise picked up in the power line driving the 6N138. This filter may not be strictly necessary, but adding it removed the noise shown on the oscilloscope when testing.

The hardware is mounted on a vero board inside a sealed polycarbonate enclosure.

The above photos show the layout of the components, before adding the connecting wires and mains wiring. Note the cleared areas of the vero board. Around the 240V part of the circuit and under the ESP2866 aerial and under the power supply board which is secured with two part epoxy to the vero board. (The slot under the opto-isolator is probably not strictly necessary as nothing will protect you against a really good lighting strike.)

On the top of the board there are 4 x 2pin headers, marked. These allow you to power the board from 5V and program, test and debug the software without using mains power.

There are no metal parts connecting the outside to the inside of the enclosure. Also note the strain relief, using a tie wrap, on the incoming and outgoing power cables which set in tight slots cut in top edge of the base of the enclosure.

After completing the wiring as per the above schematic, you can program and test the board. DO NOT apply AC power yet!!

Step 3: Software Programming

SAFETY NOTE:DO NOT plug in the power cable. All programming and program testing/debugging can be done without applying mains power.

Programming the Timer Sketch

To program the shield follow the instructions given on https://github.com/esp8266/Arduino under Installing With Boards Manager. When opening the Boards Manager from the Tools → Board menu and select Type Contributed and install the esp8266 platform. This project was compiled using the ESP8266 version 2.2.0. Later versions well be better but may have their own bugs as the platform is evolving rapidly. (e.g. the Arduino ESP8266 board library V2.3.0 has problems connecting to access points so avoid that version.)

Close and re-open the Arduino IDE and you can now select “Generic ESP8266 Module” from Tools → Board menu.

To compile the ESP8266_FanTimer.ino sketch you will need to install two libraries, pfodESP8266BufferedClient library V2.3 and the DebouncedSwitch library V3.0.

  1. Download this pfodESP8266BufferedClient.zip file to your computer, move it to your desktop or some other folder you can easily find
  2. Then use Arduino 1.6.5 IDE menu option Sketch → Import Library → Add Library to install it. (If Arduino does not let you install it because the library already exists then find and delete the older pfodESP8266BufferedClient folder and then import this one)
  3. Stop and restart the Arduino IDE and under File->Examples you should now see pfodESP8266BufferedClient.

Do the same for the DebouncedSwitch.zip. If you have previously installed the pfodESP2866WiFi library, delete that library directory completely.

To program the board, connect the USB to Serial cable as shown on the schematic. Add a shorting link to the Programming Link and apply power to start up the ESP8266 in flash programming mode.

Then click the Arduino download button to compile sketch and download it to the ESP8266-01. The relay will click a number of times as it connected to the Rx line. Once the download as started you should remove the programming link. When the download is completed, the board reboots in normal operating mode and you can open the Arduino IDE serial monitor (set to 115200 baud) to see the sketch's debug messages if you uncomment the
#define DEBUG
line near the top of the sketch

Once the board reboots, the relay should turn on for 10 secs and then turn off. You can test the software by shorting out the Testing Link to simulate AC power being applied to the opto-isolator. Follow the Fan Timer Operating Instructions to test out the various functions.

Step 4: Final Testing

Once you have completed the software programming and testing using a 5V supply, you can seal up the enclosure and do a final test using AC power before installing the timer in the roof space.

WARNING – Mains Power can Kill You. Do not apply Mains power unless the enclosure is completely sealed and all the plugs and sockets are connected and closed.

To test the timer, plug it into a double power point, starting with both switches off, and plug a lamp into the controlled plug base (socket) as shown above.

Turn both switches off and then turn on the AC power switch, the one with the twin core power cable. The lamp should go on for 10 sec and then turn off. Next operate the other power switch to simulate turning the ceiling light on and off. This should operate the fan timer as per the operating instructions.

Step 5: Installation

WARNING – Mains Power can Kill You or Catch Fire

This project changes the use of the existing mains wiring in your house. You need to get an electrician to do these house wiring changes.

After final testing, you can arrange for an electrician to install the timer in your ceiling. Above is a schematic of a typical existing two switch light / fan installation (pdf).

Installation consists of replacing the double wall switch with a single one and adding a power plug base (socket) connected in parallel with the light.

When the double wall switch is replaced with a single the power leads that used to control the fan are just connected together so that the existing Fan Plug Base is now always powered. This Plug Base is use to supply AC power to the timer. The extra plug base (socket) connected in parallel with the light provides the Active signal input to the timer to let it detect when the light is on and off.

The second circuit above is the circuit with the timer installed (pdf).

Step 6: Preparing for Failure

Once the timer is installed and running correctly the most likely source of failure is one of the capacitors in the power supply. If the fan does not appear to be working correctly, the first thing to do is to reset the Fan Timer.

Resetting/Testing the Fan Timer

Turn off the light switch and then turn off the mains power for 20 seconds.
Then turn the mains power back on and the Fan should start running and turn itself off after 10 secs.
Resetting the Fan Timer does not change the set time or the hotspot name that has been configured.

If the fan does not start running or does not turn off after 10secs then the timer is faulty. Using the plugs and sockets installed, you can quickly take down the fan and un-plug the timer and plug the fan into the extra plug base connected in parallel with the light base. This will then turn the fan on and off with the light until you can repair and re-install the timer.


This Fan Time retrofit is simple to configure via a web page and includes a manual override to switch off the fan if needed. The installation is straight forward and if the timer fails it is easy to revert to a fan that just turns on and off with the light.

<p>Update 8th Nov 2016 revised circuit and code to improve reliability</p>
<p><strong style="">Update 28</strong><sup style=""><strong>th</strong></sup><strong style=""> Sept 2016 &ndash; DebouncedSwitch V3.0 has improved AC noise rejection</strong></p>

About This Instructable




More by drmpf:Custom Arduino Controls for Android -- No Android Programming Required High Accuracy Remote Data Logging Using Mulitmeter/Arduino/pfodApp Remote High Speed Data Logging using Arduino/GL AR150/Android/pfodApp 
Add instructable to: