Arduino Control of a 4-wire Fan

What is a 4-wire fan?

The 4-wire fan is often used to cool electronic devices such as the CPU and enclosure of a desktop PC. The 4-wire connection allows an external control device to vary the fan speed as well as monitor the rotational velocity. This is a desirable energy saving feature as the controlled fan operates at the minimum necessary speed. From a human factors perspective, the slower (optimal speed) fan is preferred at it has less acoustic noise pollution.

This engineering brief demonstrates how to monitor and control the 4-wire fan using an Arduino microcontroller. As shown in Figure 1, we will use the Arduino Nano Every and the Delta Electronics AUB0912HJ-00.

Figure 1: The Delta Electronics AUB0912HJ-00 4-wire fan is monitored and controlled by an Arduino Nano Every microcontroller.

Video 1: Demonstration of integral control over the fan’s rotational velocity. Note that the BK Precision 1550 power supply is powering the Arduino via its front panel USB port.

What is the purpose of each wire associated with the 4-wire fan?

The 4-wire fan features a brushless DC motor with an integrated motor drive. This fan plus motor controller circuitry is designed for simple integration into a larger system such as the motherboard controller of a desktop computer.

The integral motor controller has two connections for power (12 VDC typical). It also has an input wire for speed control and a tachometer output wire. The connections for the AUB0912HJ-00 are as follows:

  • red: positive 12 VDC
  • black: 12 VDC return. This is also a common ground for the control logic wires
  • yellow: speed control using a Pulse Width Modulation (PWM) drive signal
  • blue: tachometer with an open collector output

How is the PWM signal interpreted by the motor?

The speed of the representative AUB0912HJ-00 Delta Electronics fan is controlled by a Pulse Width Modulation (PWM) signal. Recall that a PWM signal is a square wave with a fixed frequency. The intelligence (fan speed) is encoded as the pulse width (on time) of the square wave. In this application, the fan’s integral motor controller is designed for a logic level waveform with a frequency of 25 kHz. The fan will begin rotation when the duty cycle is about 40 %. The fan will be at full power when the duty cycle is 100%

Tech Tip: Pulse Width Modulation is a form of communication. In some respects, it is like the familiar Amplitude Modulation (AM) or Frequency Modulation (FM) broadcasts. In all cases, we communicate by impressing an intelligence signal over a high frequency carrier. With PWM, the frequency of the carrier is fixed, and we modulate the pulse width. The term duty cycle is used to describe the intelligence impressed on the signal. Duty cycle is defined as the fraction time the signal is on relative to the total signal time. For example, let the frequency be 25 kHz. A signal with a 25 % duty cycle would have an on time of 10 us and a total signal time of 40 us. For additional information please see this Arduino note.

What is the nature of the tachometer output?

A tachometer is designed to respond to the rotational speed of the fan. For example, your bicycle may be equipped with a speed sensor. In this application, a small permanent magnet is installed one of the spokes. A Hall effect sensor is then installed to detect the magnet. The resulting tachometer will provide a pulse for every revolution of the tire.

The fan’s tachometer circuit is slightly more advanced. Instead of a single pulse, it provides a square wave output. It effectively divides the fan into 4 quadrants. The square wave transition 4 times per revolution with a signal that is logic high for quadrants 1 and 3 and low for quadrants 2 and 4.

How is the tachometer used to measure motor speed?

The rotational velocity of the fan may be determined using one of several techniques including:

  • pulse counting based on the rising edge or by counting each and every signal transition. Note that change detection identifies rising and falling edges. It doubles the number of detected events.

  • measuring the time associated with the pulse width
    As an example, consider a fan that is rotating at 4200 RPM (70 revolutions per second). With rising edge detection, we will detect 140 events per second. With change detection we would detect 280 changes per second.

With a time-measurement system, we could detect the time difference between rising edges. Given the same 4200 RPM fan, we would measure a 7.14 ms time between rising edges. That same fan operation at 1000 RPM would span 30 ms between events.

Tech Tip: The fan’s 4600 RPM rated speed may seem fast. However, from the microcontroller’s perspective this is very slow. The microcontroller is capable of measuring signals from a tachometer operating two or even three orders of magnitude faster. Also, as will be shown the sluggish measurement makes direct control of the fan’s speed very difficult. To better appreciate the microcontrollers capability to measure mechanical system please see this article involving quadrature encoders.

How is the Arduino physically connected to the 4-wire motor?

The fan to Arduino connection can be seen in Figure 1. Observe that the yellow PWM signal is connected to pin D3. The blue tachometer wire is connected to pin D2 with an LED and integral resistor to provide a pull up resistor for the open collector connection.

The fan is then powered by a 12 VDC source via the red and black wires. Note that the return for the 12 VDC power supply shares a common ground with the Arduino.

How does the Arduino control the fan motor speed?

The speed for the 4-wire fan is controlled by a PWM signal. According to the fan’s datasheet, this PWM drive signal should have a frequency of 25 kHz.

This requirement presents a problem as the Arduino Nano Every’s default PWM frequency is 976 Hz. Experiments show that the fan does operate with this mismatch. However, this is a good learning opportunity to explore microcontroller PWM techniques and look behind the curtain to see how hardware timers are incorporated into the Arduino. For more information, please see this related article that demonstrates how to configure the Arduino Nano Every for a 32 kHz 8-bit PWM. The technique is simple, but the reverse engineering process does require time to understand the Arduino IDE hardware abstraction and the design of the internal workings of the ATmega4809.

Program for manual speed control

This short Arduino sketch shown how to control the fan speed based on the input from a potentiometer. From within the setup( ) function we see the PWM is configured for 32 kHz. We also configure the output pins and instantiate the serial interface.

Download the sketch here: fan_simplified.ino (1.8 KB)

From within the loop( ) function we read the desired manual setting from the potentiometer. The 10-bit result is truncated to 8 bits and sent to the PWM. The speed of the fan is measured and sent to the serial monitor.

Note that the code uses an ISR with flag and mailbox synchronization to transfer variables from the ISR to the main code. Please see this article for a description of the synchronization. Be sure to grok the term “atomic” as it relates to indivisible units of memory transfer within the microcontroller.

Tech Tip: The term grok implies that a person has a deep intuitive understanding of a topic. In this application, there is a fundamental synchronization issue that must be addressed when transferring data between asynchronous parts of your microcontroller. Without proper attention you will find yourself chasing intermittent bugs associated with corrupt data. The flag and mailbox synchronization used in this document’s example code is a good place to start. Later, you may experiment with activating and deactivating global interrupts to safeguard critical section(s) of your code.

Program for automatic speed control

At this point we have a method to control the fan speed and a reliable method of monitoring the actual speed. The next logical step is to implement a closed loop control system to adjust the speed. A natural solution is the Proportional Integral Derivative (PID) controller. While this is an excellent idea, we find that the PID is a poor match for the fan. There is a large mismatch between the fan’s dynamics and our ability to monitor the fan’s rotational velocity.

As a rule of thumb, a digital implementation of a PID controller requires the measurement system to operate about ten time faster than the time constant \tau of the system being controlled. This fan has a time constant of several hundred microseconds. Unfortunately, our ability to measure the rotational velocity is about the same order of magnitude especially when the fan is operating at low speeds. Attempt to implement P or PI controller resulted in a surging system. The problem is compounded by our human sensitivity to changes in pitch. Any instability or hunting of fan speed will be immediately heard.

The fan control may still be useful for PID control of a thermal system. Instead of measuring the velocity of the fan we could measure the temperature of a system. We could then use PID or simply a P system to regulate the temperature.

Tech Tip: The word time constant (tau or \tau) is used to describe dynamic response a simple first-order system such as the velocity of the fan. You may recall this concept from your study of Resistor Capacitor (RC) time constants. Recall that one time constant is required for a system to reach 63% of the final value.

Use of an exclusive integral controller

Before concluding we should mention that the fan responds well using integral control. We can say this because the fan is a very simple system with non-critical system demands. This is a good academic exercise that demonstrates the relatively long-tailed response as demonstrated in Video 1.

You can download the demo code here:fan.ino (2.7 KB). Once again, we find an ISR with flag and mailbox synchronization.

We will save a full PID discussion for another day. However, the fundamental control is based on these statements:

  float error = setpoint - RevPerMin;

  if (fabs(error) > 50) {  // Lockout to prevent wandering
      integral = integral + (error * KI);
      integral = limit(integral, -255, 255);

The integral variable is an accumulator that accumulates or grows over time. Every loop iteration we add a fractional component of error to the accumulator. The resulting term is then used to drive the fan via the PWM. The polarity is such that the accumulated error is driving the system toward the setpoint thereby eliminating the error. A representative step response is shown in Figure 2. This lazy response was also featured in video 1.

Figure 2: The integral controlled system is slow to respond to a step change requiring over 30 seconds for the measured fan speed (orange) to reach the setpoint (blue).

Parting thoughts

The Arduino microcontroller may be used to control and monitor the rotational speed of a 4-wire fan. The interface is very simple requiring only a single external or internal pull up resistor for the tachometer’s signal.

At first glance the fan looks like a low-cost way to implement a PID control system as it is low cost with a simple Arduino interface. Unfortunately, the systems dynamics are less than ideal. The resulting poorly behaved system would only confuse a student who is attempting to learn control theory. Still, it serves as a counter example showcasing the importance of time constants and timely measurements of the parameter that is to be controlled.

Please leave your comments and suggestions below. Kindly include pictures if you were able to integrate this 4-wire fan into your project. Also, stay tuned as we explore other PID control systems. We will present a servo motor system that provides a satisfying and snappy response.

Best Wishes,


Be sure to see this link for related Arduino education content.

About the Author

Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians. Dahlen has returned to his Northern Minnesota home and thoroughly enjoys researching and writing articles such as this. LinkedIn | Aaron Dahlen - Application Engineer - DigiKey