PID Control of DC Fan with Arduino and Ultrasonic Sensor: A Step-by-Step Tutorial

PID control is a widely used control method in industrial and manufacturing processes, and it can also be applied to control the speed of DC fans. In this tutorial, we will show you how to use an Arduino, an ultrasonic sensor(HC-SR04), and a PID algorithm implemented in Arduino to control the speed of a DC fan.

Before we begin, it is important to understand the basic concepts of PID control. PID stands for Proportional, Integral, and Derivative. These three terms describe the three components of the PID algorithm. The Proportional component compares the current error with the setpoint and adjusts the output accordingly. The Integral component sums up the errors over time and adjusts the output to eliminate any steady-state errors. The Derivative component compares the current error with the error from the previous iteration and adjusts the output to reduce the rate of change of the error.

To build the circuit, you will need an Arduino board(Arduino Nano is used here), an ultrasonic sensor(HC-SR04), a DC fan, a transistor(TIP122), and a few other components. The ultrasonic sensor will be used to measure the distance between the sensor and an object, and this distance will be used to control the speed of the fan. To learn basics of distance measurement with ultrasonic sensor see the tutorial How to measure distance with HC-SR04 and Arduino. The TIP122 transistor will be used to control the power to the fan, and the Arduino will be used to control the transistor and the fan speed. To learn how to use transistor like TIP122 as power switch with Arduino see the tutorial Arduino Nano with TIP122 DC Motor speed Control.

The following is the circuit diagram for the PID Control of DC Fan with Arduino Nano and Ultrasonic Sensor.

PID Control of DC Fan with Arduino and Ultrasonic Sensor circuit diagram

The first step is to connect the ultrasonic sensor to the Arduino. The ultrasonic sensor has four pins: Vcc, Trig, Echo, and GND. Connect Vcc to 5V, Trig to pin 8, Echo to pin 9, and GND to GND. Next, connect the transistor to the fan. The transistor has three pins: Base, Collector, and Emitter. Connect the base to pin 9 via 1KOhm resistor, the collector to the positive terminal of the fan, and the emitter to GND. Finally, connect the negative terminal of the fan to GND. Place a 1n4148 diode across the DC motor with cathode connected to the +12V DC power supply. Also place a 0.1uF across the DC motor terminals. Connect the 12V power supply ground with the Arduino ground.

The above circuit diagram build with the help of breadboard is shown below.

Arduino Nano,Ultrasonic DC motor PID Controller

Arduino Nano,Ultrasonic DC motor PID Controller on breadboard

Once the circuit is built, it is time to upload the code to the Arduino. The code for this tutorial is available below, and it includes comments to help you understand how the code works. The code uses the ultrasonic sensor to measure the distance between the sensor and an object, and it uses this distance to control the speed of the DC fan motor.

const int fanPin = 9;
const int trigPin = 4;
const int echoPin = 3;

const int minDistance = 3; // in cm
const int maxDistance = 16; // in cm

 //define some constants
   float duration, distance;
   
//Specify initial PID tuning parameters
   const int kp = 2;
   const int ki = 5;
   const int kd = 1;

   float setPoint = 8.5;
   float error,derivative; 
   int fanSpeed = 0;
   int PWM;
   int previousError = 0;
   int integral = 0;


float getDistance();

   void setup() {
     Serial.begin(9600);
   pinMode(echoPin, INPUT);
     pinMode(trigPin, OUTPUT);
     pinMode(fanPin, OUTPUT);   
}
   
 void loop() {
    distance = getDistance();
    
    if (distance >= minDistance && distance <= maxDistance) {
     error = setPoint - distance;
     derivative = error - previousError;
     integral += error;
     previousError = error;
     
     fanSpeed = kp * error + ki * integral + kd * derivative;
          if(distance >= 8.5){
            PWM = abs(map(fanSpeed,0,76,0,150));
          }
           else{
            PWM = abs(map(fanSpeed,0,51,0,150));
          }
           analogWrite(fanPin, PWM);
          }
    else {
      PWM = 0;
      analogWrite(fanPin, PWM);
    }
    
     Serial.println("-----Data------");
     Serial.print("distance: ");
     Serial.print(distance);
     Serial.println(" cm");
     Serial.print("error: ");
     Serial.println(error);
     Serial.print("integral: ");
     Serial.println(integral);
     Serial.print("integral: ");
     Serial.println(integral);
     Serial.print("derivative: ");
     Serial.println(derivative);
     Serial.print("FanSpeed: ");
     Serial.println(fanSpeed);
     Serial.print("PWM: ");
     Serial.println(PWM);
     Serial.flush();
     delay(1000);    
   }

float getDistance() {
  //send trigger signal
   digitalWrite(trigPin, LOW);
   delayMicroseconds(2);
   digitalWrite(trigPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(trigPin, LOW);
   //calculate duration
   duration = pulseIn(echoPin, HIGH);
   //return distance
   return (duration / 2) / 29.1;
}

This Arduino code is programmed to control a DC fan using a PID controller, with ultrasonic distance measurement as the input. The fan and distance sensor are connected to specific pins on the microcontroller (9, 4, and 3, respectively). The fan speed is determined by the distance from the sensor to an object, with a target distance of 8.5 cm.

The constant variables minDistance and maxDistance define the range within which the fan speed will be adjusted. kp, ki, and kd are the coefficients for the PID controller. The variable setPoint represents the target distance, and error, derivative, and integral are used in the calculations for the PID controller.

In the setup() function, the serial communication is initialized, and the pin modes for the echo, trigger, and fan pins are set. In the loop() function, the distance is measured, and the error, derivative, and integral are calculated. Then, the fan speed is determined by the PID controller, and the fan is set to that speed using PWM. The distance, error, integral, derivative, fanSpeed, and PWM are printed to the serial monitor. The getDistance() function sends a trigger signal to the distance sensor and calculates the distance based on the duration of the echo.

Once the code is uploaded, the fan should start to spin at a low speed. As you move an object closer to the ultrasonic sensor, the fan speed should increase. You can adjust the setpoint in the code to change the desired distance at which the fan should be at full speed. If you are having trouble getting the fan to work, check the connections and make sure that the components are connected correctly.

The following video demonstrates how the Arduino and ultrasonic sensor HC-SR04 based DC motor PID controller works.


The working principle of this PID controller is illustrated in the following animation video.


  In conclusion, controlling the speed of a DC motor fan using an Arduino, an ultrasonic sensor, and a PID algorithm is a simple and effective way to control the speed of a DC fan. This tutorial has provided you with the information and resources you need to build your own circuit and control the speed of your DC fan. With a little bit of practice, you'll be able to control the speed of your DC fan with precision and accuracy.

Post a Comment

Previous Post Next Post