KeithMcLintockMark Wattrus
Published © MIT

Bathroom Extractor Fan - NodeMCU with Blynk

Get an extractor fan to automatically turn on when the humidity in the bathroom exceeded a certain level and then turn off again.

BeginnerWork in progress3 hours7,813
Bathroom Extractor Fan - NodeMCU with Blynk

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
Jumper wires (generic)
Jumper wires (generic)
Relay Module (Generic)
DHT22 Temperature Sensor
DHT22 Temperature Sensor
AM2302 DHT22 Temperature and humidity sensor module
Wire Cable - By the Foot
OpenBuilds Wire Cable - By the Foot
DS18B20 Programmable Resolution 1-Wire Digital Thermometer
Maxim Integrated DS18B20 Programmable Resolution 1-Wire Digital Thermometer

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)


Read more


AM2302 DHT22 Setup


Blynk Home Sensors

  Download latest Blynk library here:

  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials:
    Sketch generator: 
    Blynk community:  
    Follow us:        

  Blynk library is licensed under MIT license
  This example code is in public domain.


  This example shows how value can be pushed from Arduino to
  the Blynk App.

  For this example you'll need Adafruit DHT and DS18B20 sensor libraries:


/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#include <OneWire.h>

#define ONE_WIRE_BUS D3 // DS18B20 on NodeMCU D3 pin
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XXXXXXXXXXXXXXX";
char pass[] = "XXXXXXXXXXXXXXX";

/* DS18B20 Temperature Sensor */
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float temp_0;
float temp_1;
float temp_2;

#define DHTPIN 2          // What digital pin we're connected to
#define DHTTYPE DHT22     // DHT 22, AM2302, AM2321

BlynkTimer timer;

// MW: Declare variable out here so they can be accessed in other sub-function, such as checkDelayTimer. I think if you declare them inside the sub-function it is only accessible there. So these would be called global variables.
float h = 0;
float t = 0;
int delayCountdown = 0; // Use this for countdown timing

void sendSensor()
  h = dht.readHumidity();
  t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

//  if (isnan(h) || isnan(t))
//    Serial.println("Failed to read from DHT sensor!");
//    return;

  temp_0 = DS18B20.getTempCByIndex(0); // Sensor 1
  temp_1 = DS18B20.getTempCByIndex(1); // Sensor 2 
  temp_2 = DS18B20.getTempCByIndex(2); // Sensor 3 

  Serial.print("Temp_0: ");
  Serial.print(" oC . Temp_1: ");
  Serial.print(" oC . Temp_2: ");
  Serial.print(" oC . Temp_3: ");
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V0, t);
  Blynk.virtualWrite(V1, h);
  Blynk.virtualWrite(V3, temp_0); //virtual pin V3
  Blynk.virtualWrite(V4, temp_1); //virtual pin V4
  Blynk.virtualWrite(V5, temp_2); //virtual pin V5

void checkHumidity()
  // First chech if humidity has triggered. I'm working on the assumption you want to turn on the fan when the humidity is above 99%? Does the sensor ever see such a high humidity?
  // I'm also assuming HIGH is to turn on the fan. Swap HIGH and LOW if not the case.
  if ( (h > 99) && (delayCountdown == 0) )  // Set countdown timer if humidity triggered and timer not currently running
    delayCountdown = 600;   // Set the countdown timer to 600 seconds
    digitalWrite(13, LOW);  // If this board is the NodeMCU, consider using D7 in your commands instead of the GPIO pin number 13 and so on. You would need to change it everywhere. These are mapped behind the scene for ease of reference. E.g. digitalWrite (D7, HIGH)
    Blynk.virtualWrite(V2, LOW);    // Update the button on Blynk when the humidity trigger turns on the fan.
  if (delayCountdown == 1)  // Turn off fan if countdown has reached the last 1 second
    digitalWrite(13, HIGH);
    Blynk.virtualWrite(V2, HIGH);    // Update the button on Blynk when the fanis turned off from the countdown timer.
  if (delayCountdown > 0)
    delayCountdown--; // If above 0, decrement delayCountdown every second since this loop runs every second. If triggered it would have been set at 600s above.       
  // If the countdown timer equals 0 and the fan is on, this means it has been switched on manually using the Blynk button. We don't need to do anything for this case.

void setup()
  // Debug console
  Blynk.begin(auth, ssid, pass);
  DS18B20.begin();  // Start DS18B20 communication
  dht.begin();      // Start DHT22 communication
  // Setup a function to be called every second
  timer.setInterval(1000L, sendSensor);
  timer.setInterval(1000L, checkHumidity);  // MW: Check humidity and how much time has passed every second so we don't block the main loop from running
  pinMode (13, OUTPUT);

  int buttonState = param.asInt();
  digitalWrite(13, buttonState);  // Just do manual on and off here

void loop()

DHT Sensor Library

Blynk Library

DS18B20 Temp Library


Keith McLintock

Posted by KeithMcLintock
Thanks to Christiaan Nel and Mark Wattrus.


Add projectSign up / Login