top of page
Writer's pictureRamesh G

Temperature Controlled Fan using DS18B20 and Arduino

Updated: Jun 3, 2021

In this to learn step by step guide and we will show you how to make a temperature-controlled fan using Arduino, DS18B20 and interface with LCD display, and DC fan that is controlled by using PWM.

The most important part is to set the variables temp Min and temp Max with your desired values. temp Min is the temperature at which the fan starts to spin and temp Max is the temperature when the red led lights warning you that the maximum temp was reached. For example if you set temp Min at 20 and temp Max at 40 then the fan will start spinning (0%) at 20°C and reach its maximum speed (100%) at 40°C. Example: If current Temperature 35°C, then Fan Speed 85%.


Circuit Diagram:


Components Required

Arduino Uno - 1 no

LCD display 16x1- I2C- 1 no

DS18B20 with Probe - 1 no

Fan 5VDC - 1 no

Transistor 2N2222- 1 no

Resistor 220E- 1 no


DS18B20


Arduino UNO (PWM)

Working on this project is very simple. We have created PWM at D8 pin of arduino and applied it at base terminal of the transistor. Then transistor creates a voltage according to the PWM input.

PWM is a technique by using we can control the voltage or power.

Formula for duty cycle given below:

Duty Cycle= Ton/T

Where T= total time or Ton+Toff

And Ton= On time of pulse (means 1 )

And Toff= Off time of pulse (means 0)

For generating PWM we have used “analogWrite(pin, PWM value)” fuction in 8 bit. Mean if PWM value is equivalent of analog value. So if we need to generate 100% of duty cycle then we pass 255 value as PWM in “analogWrite” Function.

A low-frequency pulse-width modulation (PWM) signal, whose duty cycle is varied to adjust the fan’s speed is used. An inexpensive, single transistor-like 2N222 or BD139 can be used to drive a small DC Fan.


Installing the Arduino Library

LiquidCrystal_I2C.h : you need to Download and install the LiquidCrystal_I2C library.


Installing Libraries for DS18B20

To interface with the DS18B20 temperature sensor, you need to install the One Wire library . Follow the next steps to install those libraries.


1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.


2. Type “onewire” in the search box and install the OneWire library by Paul Stoffregen.

In your Arduino IDE, to install the libraries go to Sketch > Include Library > Add .ZIP library… and select the library you’ve just downloaded.


After installing the required libraries, copy the following code to your Arduino IDE.


Subscribe and Download code.



Arduino code:


include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example

// http://www.pjrc.com/teensy/td_libs_OneWire.html

OneWire ds(5); // on pin 10 (a 4.7K resistor is necessary)

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);


int Fan = 11; // the pin where fan is

int led = 8; // led pin

int temp;

int tempMin = 20; // the temperature to start the fan 0%

int tempMax = 40; // the maximum temperature when fan is at 100%

int fanSpeed;

int FanPWM;


void setup(void) {

Serial.begin(9600);

lcd.init(); // initialize the lcd

// Print a message to the LCD.

lcd.backlight();

pinMode(Fan, OUTPUT);

pinMode(led, OUTPUT);


}


void loop(void) {

byte i;

byte present = 0;

byte type_s;

byte data[12];

byte addr[8];

float celsius, fahrenheit;

if ( !ds.search(addr)) {

Serial.println("No more addresses.");

Serial.println();

ds.reset_search();

delay(250);

return;

}

Serial.print("ROM =");

for( i = 0; i < 8; i++) {

Serial.write(' ');

Serial.print(addr[i], HEX);

}


if (OneWire::crc8(addr, 7) != addr[7]) {

Serial.println("CRC is not valid!");

return;

}

Serial.println();

// the first ROM byte indicates which chip

switch (addr[0]) {

case 0x10:

Serial.println(" Chip = DS18S20"); // or old DS1820

type_s = 1;

break;

case 0x28:

Serial.println(" Chip = DS18B20");

type_s = 0;

break;

case 0x22:

Serial.println(" Chip = DS1822");

type_s = 0;

break;

default:

Serial.println("Device is not a DS18x20 family device.");

return;

}


ds.reset();

ds.select(addr);

ds.write(0x44, 1); // start conversion, with parasite power on at the end

delay(1000); // maybe 750ms is enough, maybe not

// we might do a ds.depower() here, but the reset will take care of it.

present = ds.reset();

ds.select(addr);

ds.write(0xBE); // Read Scratchpad


Serial.print(" Data = ");

Serial.print(present, HEX);

Serial.print(" ");

for ( i = 0; i < 9; i++) { // we need 9 bytes

data[i] = ds.read();

Serial.print(data[i], HEX);

Serial.print(" ");

}

Serial.print(" CRC=");

Serial.print(OneWire::crc8(data, 8), HEX);

Serial.println();


// Convert the data to actual temperature

// because the result is a 16 bit signed integer, it should

// be stored to an "int16_t" type, which is always 16 bits

// even when compiled on a 32 bit processor.

int16_t raw = (data[1] << 8) | data[0];

if (type_s) {

raw = raw << 3; // 9 bit resolution default

if (data[7] == 0x10) {

// "count remain" gives full 12 bit resolution

raw = (raw & 0xFFF0) + 12 - data[6];

}

} else {

byte cfg = (data[4] & 0x60);

// at lower res, the low bits are undefined, so let's zero them

if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms

else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms

else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms

//// default is 12 bit resolution, 750 ms conversion time

}

celsius = (float)raw / 16.0;

fahrenheit = celsius * 1.8 + 32.0;

Serial.print(" Temperature = ");

Serial.print(celsius);

Serial.print(" Celsius, ");

Serial.print(fahrenheit);

Serial.println(" Fahrenheit");

lcd.setCursor(0,0);

lcd.print("C:");

lcd.print(celsius);

lcd.setCursor(9,0);

lcd.print("F:");

lcd.print(fahrenheit);


/////

temp = celsius; // get the temperature

Serial.print( temp );

if(temp < tempMin) // if temp is lower than minimum temp

{

fanSpeed = 0; // fan is not spinning

analogWrite(Fan, fanSpeed);

FanPWM=0;

digitalWrite(Fan, LOW);

}

if((temp >= tempMin) && (temp <= tempMax)) // if temperature is higher than minimum temp

{

fanSpeed = temp;//map(temp, tempMin, tempMax, 0, 100); // the actual speed of fan//map(temp, tempMin, tempMax, 32, 255);

fanSpeed=1.5*fanSpeed;

FanPWM = map(temp, tempMin, tempMax, 0, 100); // speed of fan to display on LCD100

analogWrite(Fan, fanSpeed); // spin the fan at the fanSpeed speed

}

if(temp > tempMax) // if temp is higher than tempMax

{

digitalWrite(led, HIGH); // turn on led

}

else // else turn of led

{

digitalWrite(led, LOW);

}


lcd.setCursor(0,1); // move cursor to next line

lcd.print("FAN SPEED: ");

lcd.print(FanPWM); // display the fan speed

lcd.print("%");

lcd.print(" ");

delay(200);

//lcd.clear();

}


After a successful upload, open the Serial Monitor at a baud rate of 9600. Press the “EN/RST” button on the Arduino Uno board and see the result in monitor.




2,525 views6 comments

6 Comments


fjdejonge36
May 17, 2023

Hello,

can you help me one a code for a pwm fan 4 pins with tacho 200 rpm till 3300rpm

DS18b20 and oled and 1 relay to switch a pump.

normal situation fan will run on 25% till 30 deg. after this the fan will raise up and relay will turn on.

o-led p.96 screen is a i2c libary is standaard. o-led must give actuele temperature in deg.

and relays OFF under the 30 deg after 30 deg relay ON.

systemboard is andruino uno r3 type


please let me now.

many thanks

Frank

Like

Just use a PWM fan its way easier

Like

Ramesh G
Ramesh G
Jan 13, 2022

LED current limiting resistor is 220 ohms (red,red, brown), Transistor driver resistor value is 220ohms, it may be CFR or MFR.

Transistor UNO 2N2222 is used to drive the fan speed control using PWM pin of UNO.( Fan DC5V 0.2A.)

In this project you cannot use relay, because Relay have the capabilities ON/OFF of the device. You cannot control FAN speed with respect to temperature using relay.


Like

Mike Landis
Mike Landis
Jan 11, 2022

Actually, looking again, it seems that the resistor from VCC to the data pin on the DS18B20 is only 47 ohms (yellow, violet, black). Is that right?

Like
Ramesh G
Ramesh G
Jan 13, 2022
Replying to

This is for MFR resistor, so that you consider count 4 color for resistor value and 5th color for tolerance. Other two resistor used CFR resistor in this project.

Like

Mike Landis
Mike Landis
Jan 11, 2022

First, I very much appreciate your post, but I'm a little confused - there are three resistors shown on the schematic ... a 4.7 kohm for the DS18B20 data line, a 220 ohm for the LED, and what appears to be a (red, red, black) 22 ohm resistor from the PWM PB3-11 pin to the base of the transistor (though I have yet to discover where you spec'd that). Do I have that right?


I don't see anything Arduino specific in the schematic, except for which pins on the Uno board are used - seems easy enough to connect to similar pins on a Pi Zero.


No problem running a fan on Uno power? I saw a pos…

Like
bottom of page