Nextion Arduino Temperature Monitor Fan Controller

Nextion Arduino Temperature Monitor Fan Controller


In a search for extra spindle speed, I replaced the original spindle motor on this mill with a servo motor. This is a 750W servo and after running an hour its temperature can reach 100 C. The first motor mounts I made had some cork to isolate vibrations, but I removed that. There are no vibrations from the servo and the cork prevented the servo heat from being dumped into mill head. Next I added a fan and a shroud around the motor to duct the cooling air near the servo. But the fan was loud.

Someone asked me to create a touchscreen interface for Clough42’s electronic leadscrew using a Nextion display. As a project to learn about the Nextion, I created a fan controller. The controller contains an Arduino Uno to read the servo temperature from an IR sensor, the fan’s tach, update the fan’s speed, and update the touchscreen display.

This video goes over details of project including problems. The project files can be found on my GitHub repository. Let’s get to work.

While probably not entirely needed, I added a cooling fan to the servo motor that drives the spindle on my CNC mill conversion. With a 750W servo, assuming 90% efficiency, there’s potentially 75W of heat being produced. A shroud around the servo forces air to move along and near the servo. Now, I like a quite environment, and fans that move a lot of air are loud. I only wanted to have the fan on when needed.

I first considered fans with built-in temperature sensors and various thermistor compatible fan controllers. Either of these would have been fine. Then someone asked if I would make them a touchscreen interface to Clough42’s electronic leadscrew using a Nextion display. Before agreeing to help I needed learn about the display. So, I made a fan controller.

The fan controller shows run time, current temperature, and current fan speed. The temperature and fan speed are plotted on a scrolling graph. Touching the run time resets the run time to zero. Touching the temperature toggles the units between Celsius and and Fahrenheit. And touching the fan speed changes the fan speed mode between off, minimum, maximum, and the default of automatic.

A Nextion touchscreen display and Arduino Uno together monitor the temperature of a 750W AC servo motor and control a cooling fan. IR based non-contact and contact temperature sensors are compared. I2C interfacing across voltage regions considered. Introduction to Nextion programming. The AC servo drives the spindle on a DIY CNC mill where the servo may operate for hours.

Full notes

Full notes for this document are available on Notion.

Controller choice

The minimal features: Turn a fan on when the servo is warm and then control the fan’s speed proportional to the servo’s temperature. Deciding on a controller seems a good first starting point.

The easiest controller would be to simply turn the fan on when the spindle is running. This could be done with a relay and a GPIO line from the CNC controller.

A voltage controlled fan, a thermistor could also be simple. Would need a transistor to control the fan with the thermistor, and perhaps an op amp as a comparator.

There might be a wider selection of PWM controled fans available. For a basic PWM signal, a 555 timer may work. The Sanyo Denki PWM controller provides greater sophistication. Up to four fans at 12, 24, or 48V. Easy but expensive in parts. Chips such as Maxim MAX31740, the Ultra-Simple Fan-Speed Controller.


I was going to share the same power supply between the brake and fan. The inductive kickback of the brake requires snubber diodes to protect the electronics, including the fan’s BLDC electronics not just the display and Arduino. With a shared ground, two 24V wires are present: one of for the brake and another for the fan. In the end, I added a second 24V supply, which was similar in price to replacing the electronics, and an SSR to control the brake.


A 120 mm fan fits to the top of the shroud surrounding the servo well. 24V is readily available and PWM seems the most versatile common control method.

I selected a 24V PWM 120mm fan from Noctua’s industrial line. There are more powerful 3- and 4- pin fans available from Digikey, but the sound levels increase. Knowing Noctua for quiet computer case fans, I was not expecting so much noise, which then caused me to want a fan controller.

Noctua NF-F12 iPPC-24V-3000 Q100 IP67 PWM, Heavy Duty Cooling Fan, 4-Pin, 3000 RPM, 24V Version (120mm, Black)

PWM notes

Would prefer if the Arduino failed that the fan run at maximum speed. No output_pullup for pinMode(). Will an external pullup resister work?

Original PWM cooling fan specification may have been put forward by Intel. A more recent Noctua white paper is easier to find and read.

PWM design notes

PWM of 25kHz is recommended for PWM controlled fans. The high frequency is outside of great hearing, which cuts off at 20kHz. The Arduino PWM is 490 or 980Hz, or roughly the two B’s above middle-C on a piano. Regardless, I don’t hear the PWM in a quiet room let alone above other noises in the shop. There are techniques to increase the PWM frequency on the Arduino, at on some pins. The lower frequency of the Arduino may be to increase the number of pins available for PWM.

With 4-wire fans, the fan electronics are always powered and so pulse stretching is not required. Pulse stretching is used with three wire fans, where the supply is PWM switched to control the fan’s speed. In this case, to read the tach, the supply must remain on as long as is required to measure the width of a tach pulse.

Noctua PWM white paper

Intel and Noctua PWM spec sheets.

Tach notes

Slight changes to this tach code.


attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) (recommended)

attachInterrupt(interrupt, ISR, mode) (not recommended)

attachInterrupt(pin, ISR, mode) (Not recommended. Additionally, this syntax only works on Arduino SAMD Boards, Uno WiFi Rev2, Due, and 101.)

Move oneWire to pin 4 to not interfere with interrupt handler

Need a deadband range, a minimal value, so is not turned on for small values.

Need some amount of hysteresis to avoid the fan rapidly turning on and off near threshold. The fan tends to remain off if already off and tends to remain on if already on.


Fan controller files are on GitHub.

Bill of materials (mostly Amazon Affiliate links):

Arduino Uno R3, DIP version:

Arduino Uno R3, SMD version:

Arduino Uno R3 Bare Shield:

Straight Headers:

Murata DC-DC Converter OKI-78SR-12/1.0-W36H-C…

Nextion Enhanced NX4832K035:

Nextion GPIO Breakout:

DS18B20-based Contact Temperature Sensor:

OTI-301-based Non-contact Temperature Sensor:

MLX90614ESF-based Non-contact Temperature Sensor:

Noctua NF-F12 industrialPPC-24V-3000 Q100 IP67 PWM: