This simple project controls the speed of a fan based on the reading from a temperature sensor.
The video below shows the fan speed changing when the temperature sensor is moved from cold water to hot water. You can hear the fan speed increase and see the readings changing on the Arduino IDE serial monitor.
For this project you need any ESP8266 development board (a NodeMCU in this case), a DS18B20 temperature sensor, a mosfet module (eBay, AliExpress), a two wire computer fan and a 12v power supply or batteries.
The 12 volts that the fan requires cannot be directly connected to the pins of the ESP8266. The ESP8266 is used to control the mosfet module which bridges the power between the fan and the power supply. The speed of the fan is controlled using PWM (Pulse Width Modulation) by switching the power on and off rapidly.
The wiring looks like this. Note the use of the resistor.
If you don’t have the OneWire and DallasTemperature libraries installed you’ll need to install them via the library manager. In the IDE menu Sketch > Include Library > Manage Libraries… Search for OneWire and install it:
Then search for Dallas and install DallasTemperature:
The code is fairly simple. There’s one function that reads the temperature of the sensor. The reading is then passed to another function that controls the speed of the fan. The line map(….) takes the value from the DS18B20 and converts it into a number between 10 and 100. More info on the map function here
// Include the libraries we need #include <OneWire.h> #include <DallasTemperature.h> #define D1 5 // fan assigning the ESP8266 pin to arduino pin #define ONE_WIRE_BUS 12 // thermometer int fanPin = 5; int dutyCycle = 0; // Setup a oneWire instance to communicate with OneWire device OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); void setup() { Serial.begin(115200); pinMode(fanPin, OUTPUT); // sets the pins as outputs: sensors.begin(); // Start up the library analogWriteRange(100); // to have a range 1 - 100 for the fan analogWriteFreq(10000); } float readSensorTemp() { sensors.requestTemperatures(); // Send the command to get temperatures Serial.print("Temperature: "); Serial.println(sensors.getTempCByIndex(0)); return sensors.getTempCByIndex(0); } void controlFanSpeed (int fanSpeedPercent) { Serial.print("Fan Speed: "); Serial.print(fanSpeedPercent); Serial.println("%"); analogWrite(fanPin, fanSpeedPercent); // set the fan speed } void loop() { float sensorTemp = readSensorTemp(); // Request sensor value // Map (change) the sensor reading of <=5 to >=60 to a value between 10 and 100 int fanSpeedPercent = map(sensorTemp, 5, 60, 10, 100); controlFanSpeed (fanSpeedPercent); // Update fan speed delay(1000); }
Note the IRF520 on the mosfet module board isn’t really the correct component for switching high currents with the low voltage signal (gate) voltage supplied by the ESP but it works for this experiment.
Buy Me A Coffee
If you found something useful above please say thanks by buying me a coffee here...
Sir, my 12v fan is not working as shown in your project. The led on the MOSFET module worked well with the analogwrite() function. However, there is no output on the MOSFET module. Please help me on my project. Thank you.
Hi. Try connecting the 3.3v from the 8266 to the VCC pin on the MOSFET module. It might need a bit more energy to switch on.
This is a great peace of information.
How would you use this logic running two sensors. One at the top of an enclosure and one on the floor. If you want to keep the temperature within one degree C and anything greater than that turns the fan on at a faster rate to blow the heat down.
I’m wanting to use two DHT22 sensors.
I don’t really have time to look at this properly but something like this in the loop..
float sensor1Temp = readSensorTemp(sensor1); // Floor sensor value
float sensor2Temp = readSensorTemp(sensor2); // Top sensor value
float sensorDifference = sensor2Temp – sensor1Temp;
int fanSpeedPercent = map(sensorDifference, 0, 1, 0, 100);
You need to double check map() https://www.arduino.cc/reference/en/language/functions/math/map/ I think with the code above, zero degrees stop the fan. From 0 to 1+ degree difference will make the fan spin between 0 and 100%.
Hi. Great project. Do you know of it could be used with fans which have 3 or 4 pins? Thanks
Hi 3 will work.. Just ignore the 3rd pin. 4 pins you would have to change the code to work with PWM. More info – https://forums.tomshardware.com/threads/fan-speed-control-how-to-2-pin-vs-3-pin-vs-4-pin.2200004/
Hello,
could you be more specific how to change code to work with PWM, please?
Thank you.
Hi, With this project I don’t know. I would have to do some tests. I found this though that might help do what you want: https://github.com/faeibson/ESPPWMFanControl
Can you share the schematic circuit sir ?
Should be a wiring diagram in the tutorial
can i use esp 12f for this project ?
Yep, but I’m not sure which pins you would use.