Smart Fan
The Smart Fan is one of my IOT projects which used a temperature and humidity sensor to control the speed of a fan connected to it. It also incorporates a LCD screen to display the readings from the temperature and humidity sensor. The project was built using an Arduino Uno, a DHT11 sensor. Below is diagram of the project for the circuitry:
How the smart fan works
The smart fan works by reading the temperature and humidity from the DHT11 sensor and then adjusting the speed of the fan based on the readings. Below is a video showing the smart fan in action:
Code
There are a few versions of the smart fan that I implemented:
- Version 1: This one is basic and just turns on the fan when the temperature is above 22 degrees farhenheit
- Version 3: This one used the PWM to control the speed of the fan based on the temperature
- Version 2: This one is modified to turn on the fan when the temperature is above 70 degrees farhenheit
- Version 4: This one is modified to play around with the DIRA and DIRB pins to control the direction of the fan
Version 1
This one is basic and just turns on the fan when the temperature is above 22 degrees farhenheit
#include <dht_nonblocking.h>
#include <LiquidCrystal.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
boolean fan_on = false;
#define ENABLE 5
#define DIRA 3
#define DIRB 6
// Initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup() {
Serial.begin(9600);
pinMode(ENABLE, OUTPUT);
pinMode(DIRA, OUTPUT);
pinMode(DIRB, OUTPUT);
digitalWrite(DIRA, HIGH); //one way
digitalWrite(DIRB, LOW);
digitalWrite(ENABLE, LOW); // enable off
// Set up the LCD's number of columns and rows:
lcd.begin(16, 2);
}
/*
* Poll for a measurement, keeping the state machine alive. Returns
* true if a measurement is available.
*/
static bool measure_environment(float *temperature, float *humidity) {
static unsigned long measurement_timestamp = millis();
/* Measure once every four seconds. */
if (millis() - measurement_timestamp > 3000ul) {
if (dht_sensor.measure(temperature, humidity) == true) {
measurement_timestamp = millis();
return (true);
}
}
return (false);
}
void loop() {
float temperature;
float humidity;
if (measure_environment(&temperature, &humidity) == true) {
if (temperature > 22.0) {
digitalWrite(ENABLE, HIGH);
if (!fan_on) {
Serial.println("High temperature - turn on fan");
fan_on = true;
}
} else {
digitalWrite(ENABLE, LOW);
if (fan_on) {
Serial.println("Low temperature - turn off fan");
fan_on = false;
}
}
Serial.print("T = ");
Serial.print(temperature, 1);
Serial.print(" deg. C, H = ");
Serial.print(humidity, 1);
Serial.println("%");
// Clear the LCD screen
lcd.clear();
// Print temperature and humidity on the LCD
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
}
}
Version 2
This one is modified to turn on the fan when the temperature is above 70 degrees farhenheit
#include <dht_nonblocking.h>
#include <LiquidCrystal.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
boolean fan_on = false;
#define ENABLE 5
#define DIRA 3
#define DIRB 6
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup() {
Serial.begin(9600);
pinMode(ENABLE, OUTPUT);
pinMode(DIRA, OUTPUT);
pinMode(DIRB, OUTPUT);
digitalWrite(DIRA, HIGH);
digitalWrite(DIRB, LOW);
digitalWrite(ENABLE, LOW);
lcd.begin(16, 2);
}
static bool measure_environment(float *temperature, float *humidity) {
static unsigned long measurement_timestamp = millis();
if (millis() - measurement_timestamp > 3000ul) {
if (dht_sensor.measure(temperature, humidity) == true) {
*temperature = *temperature * 9.0 / 5.0 + 32; // Use the Cel to Far formula to calculate the temperature in Far
measurement_timestamp = millis();
return (true);
}
}
return (false);
}
void loop() {
float temperature;
float humidity;
if (measure_environment(&temperature, &humidity) == true) {
if (temperature > 70.0) { // Change number to as temps are in F
digitalWrite(ENABLE, HIGH);
if (!fan_on) {
Serial.println("High temperature - turn on fan");
fan_on = true;
}
} else {
digitalWrite(ENABLE, LOW);
if (fan_on) {
Serial.println("Low temperature - turn off fan");
fan_on = false;
}
}
Serial.print("T = ");
Serial.print(temperature, 1);
Serial.print(" deg. F, H = "); //F instead of C
Serial.print(humidity, 1);
Serial.println("%");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" F");
lcd.setCursor(0, 1);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
}
}
Version 3
This one used the PWM to control the speed of the fan based on the temperature
#include <dht_nonblocking.h> // Include the library for non-blocking DHT sensor
#include <LiquidCrystal.h> // Include the library for LCD display
#define DHT_SENSOR_TYPE DHT_TYPE_11 // Define the type of DHT sensor
static const int DHT_SENSOR_PIN = 2; // Define the pin for DHT sensor
DHT_nonblocking dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE); // Create an instance of the DHT sensor
#define FAN_PIN 5 // Define the pin for fan control (PWM pin)
#define DIRA 3 // Define the pin for direction control A
#define DIRB 6 // Define the pin for direction control B
// Initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup() {
Serial.begin(9600); // Initialize serial communication
pinMode(FAN_PIN, OUTPUT); // Set the fan control pin as output
pinMode(DIRA, OUTPUT); // Set the pin for direction control A as output
pinMode(DIRB, OUTPUT); // Set the pin for direction control B as output
digitalWrite(DIRA, HIGH); // Set direction control A to high (one way)
digitalWrite(DIRB, LOW); // Set direction control B to low
// Set up the LCD's number of columns and rows:
lcd.begin(16, 2);
}
/*
* Poll for a measurement, keeping the state machine alive. Returns
* true if a measurement is available.
*/
static bool measure_environment(float *temperature, float *humidity) {
static unsigned long measurement_timestamp = millis(); // Initialize measurement timestamp
/* Measure once every four seconds. */
if (millis() - measurement_timestamp > 3000ul) { // Check if it's time to measure
if (dht_sensor.measure(temperature, humidity) == true) { // Measure temperature and humidity
measurement_timestamp = millis(); // Update measurement timestamp
return (true); // Return true if measurement is available
}
}
return (false); // Return false if measurement is not available
}
void setFanSpeed(float temperature) {
// Divide the temperature range into four segments and adjust fan speed accordingly
if (temperature > 19.0) {
analogWrite(FAN_PIN, 255); // Set fan speed to maximum (255)
} else if (temperature > 25.0) {
analogWrite(FAN_PIN, 200); // Set fan speed to 80% (approximately 200)
} else if (temperature > 20.0) {
analogWrite(FAN_PIN, 150); // Set fan speed to 60% (approximately 150)
} else {
analogWrite(FAN_PIN, 100); // Set fan speed to 40% (approximately 100)
}
}
void loop() {
float temperature;
float humidity;
if (measure_environment(&temperature, &humidity) == true) { // If measurement is available
setFanSpeed(temperature); // Adjust fan speed based on temperature
Serial.print("T = ");
Serial.print(temperature, 1);
Serial.print(" deg. C, H = ");
Serial.print(humidity, 1);
Serial.println("%");
// Clear the LCD screen
lcd.clear();
// Print temperature and humidity on the LCD
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
}
}
Version 4
This one is modified to play around with the DIRA and DIRB pins to control the direction of the fan
#include <dht_nonblocking.h>
#include <LiquidCrystal.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
#define ENABLE 5
#define DIRA 3
#define DIRB 6
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup() {
Serial.begin(9600);
pinMode(ENABLE, OUTPUT);
pinMode(DIRA, OUTPUT);
pinMode(DIRB, OUTPUT);
digitalWrite(ENABLE, LOW); // Initially turn off fan
lcd.begin(16, 2);
}
static bool measure_environment(float *temperature, float *humidity) {
static unsigned long measurement_timestamp = millis();
if (millis() - measurement_timestamp > 3000ul) {
if (dht_sensor.measure(temperature, humidity) == true) {
*temperature = *temperature * 9.0 / 5.0 + 32; // Convert Celsius to Fahrenheit
measurement_timestamp = millis();
return (true);
}
}
return (false);
}
void loop() {
float temperature;
float humidity;
if (measure_environment(&temperature, &humidity) == true) {
if (temperature > 80.0) {
digitalWrite(DIRA, HIGH); // Set motor direction clockwise
digitalWrite(DIRB, LOW); // Set motor direction clockwise
digitalWrite(ENABLE, HIGH); // Turn on fan
Serial.println("High temperature - Cooling mode");
} else {
digitalWrite(DIRA, LOW); // Set motor direction counter-clockwise
digitalWrite(DIRB, HIGH); // Set motor direction counter-clockwise
digitalWrite(ENABLE, HIGH); // Turn on fan
Serial.println("Low temperature - Reverse mode");
}
Serial.print("T = ");
Serial.print(temperature, 1);
Serial.print(" deg. F, H = ");
Serial.print(humidity, 1);
Serial.println("%");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" F");
lcd.setCursor(0, 1);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
}
}