A versatile embedded fan control system for precise and automated speed regulation based on user input and environmental conditions.
Explore the Docs »
·
Report Bug
·
Request Feature
- About the Project
- System Architecture
- Getting Started
- Usage
- Troubleshooting
- Roadmap
- Contributing
- License
- Contact
- Acknowledgments
The Fan Controller System is designed to control a DC fan’s speed dynamically based on user input, target RPM, or environmental conditions such as temperature. It leverages a PID control loop for closed-loop accuracy and offers multiple modes, including open-loop and automatic (temperature-based) operation.
Whether you need a stable RPM under varying loads, a fan speed that responds to temperature changes, or a manual tuning mode, this controller provides a flexible and extensible solution for embedded applications. It runs on an STM32 NUCLEO-F070RB board, interfacing with an LCD, rotary encoder, temperature sensor, LEDs, and a push button for full standalone operation—no PC required after deployment.
- Multiple Control Modes: Choose between OFF, Closed-Loop RPM control, Open-Loop control, Auto Temperature-based control, and Calibration mode.
- PID-based Closed-Loop: Precisely maintain target RPM under changing conditions.
- User-Friendly Interface: Adjust setpoints with a rotary encoder, view status on an LCD, and use a button to cycle through modes.
- Temperature Feedback: Automatically increase or decrease fan speed to maintain desired temperature.
- Dynamic Display & Indicators: LCD output for RPM, temperature, and mode status, plus LED indicators for quick status checks.
The firmware continuously reads sensors, updates control parameters, and drives the fan accordingly. It runs in a loop, calling different handlers based on the current mode.
- OFF: Fan is turned off (0% duty cycle).
- Closed-Loop (ENCDR_C_LOOP): Uses PID to maintain a user-defined RPM set via the rotary encoder.
- Open-Loop (ENCDR_O_LOOP): Sets fan speed based on a predetermined duty cycle curve and target RPM input, without feedback correction.
- AUTO: Adjusts fan speed automatically based on the measured temperature, employing a PID-like approach to reach the target temperature.
- CALIB: Attempts to map duty cycle to RPM by stepping down from full speed, useful for characterizing the fan.
| Component | Pins |
|---|---|
| LCD | PB_15, PB_14, PB_10, PA_8, PB_2, PB_1 |
| Rotary Encoder | PA_1, PA_4 |
| Fan PWM Output | PB_0 |
| Fan Tachometer | PA_0 |
| LEDs | PC_0, LED1 |
| Button | BUTTON1 |
| Serial Debug | USBTX, USBRX |
This system uses an STM32 NUCLEO-F070RB board, interfacing with:
- Fan: Controlled via PWM.
- LCD Display: Provides real-time information on mode, RPM, and temperature.
- Rotary Encoder: Adjusts target RPM or temperature.
- Button: Toggles between modes.
- LEDs: Indicates status (e.g., RPM range or errors).
-
OFF Mode:
- Purpose: Completely powers off the fan.
- Use Case: When cooling is unnecessary or to conserve power.
- Operation: All LEDs are off. The fan PWM is set to 0%.
- LCD Output:
M: OFF [Blank Line]
-
Closed-Loop Control (ENCDR_C_LOOP):
- Purpose: Maintains a precise RPM using a PID controller.
- Use Case: Critical applications requiring consistent airflow regardless of load changes.
- Operation:
- User sets the target RPM using the rotary encoder.
- PID adjusts the PWM duty cycle to maintain the target RPM.
- LED Behavior:
- Red: Low RPM (<200).
- Green: High RPM (>1750).
- Off: Normal operation.
- Green + PC_0 (LED2): Indicates a stalled fan.
- LCD Output:
M: CL. T= XXXX (Target RPM) AT=XX. RPM= XXXX (Temperature, Actual RPM)
-
Open-Loop Control (ENCDR_O_LOOP):
- Purpose: Controls fan speed using predefined duty cycle curves.
- Use Case: Non-critical systems where precise RPM is unnecessary.
- Operation:
- Rotary encoder sets target RPM.
- Duty cycle is derived from a quadratic equation, without RPM feedback.
- LED Behavior: Same as Closed-Loop Control.
- LCD Output:
M: OL. T= XXXX (Target RPM) AT=XX. RPM= XXXX (Temperature, Actual RPM)
-
Automatic Mode (AUTO):
- Purpose: Adjusts fan speed based on the current temperature to maintain a target temperature.
- Use Case: Systems requiring thermal regulation, such as server racks.
- Operation:
- Rotary encoder sets the target temperature.
- PID controller adjusts the PWM duty cycle based on temperature error.
- LED Behavior:
- Red: High temperature requiring fan boost.
- Green: Normal temperature.
- PC_0 ON: Indicates temporary boost to correct temperature quickly.
- LCD Output:
M: AL. TT = XX (Target Temperature) AT=XX. RPM= XXXX (Actual Temperature, RPM)
-
Calibration Mode (CALIB):
- Purpose: Maps the duty cycle to RPM for fan characterization.
- Use Case: When using a new fan or fine-tuning system performance.
- Operation:
- The fan starts at 100% duty cycle and steps down gradually.
- RPM is recorded at each step to create a calibration map.
- A loading bar on the LCD shows progress.
- LEDs flash alternately during calibration.
- LCD Output:
Calibrating... [Loading Bar] - LED Behavior:
- Alternate Flashing (Red/Green): Indicates ongoing calibration.
| Condition | LED BI (Bidirectional) | LED2 | Description |
|---|---|---|---|
| High RPM (>1750) | Green | OFF | Normal high-speed operation. |
| Low RPM (<200) | Red | OFF | Normal low-speed operation. |
| Stalled Fan | Red | ON | Fan is stalled despite a duty cycle > 0. |
| Calibration in Progress | Alternating Flashing | OFF | Indicates calibration mode is active. |
| OFF Mode | OFF | OFF | System is powered off. |
- Line 1: Mode and target (RPM or temperature).
- Line 2: Actual temperature and RPM.
M: XX. T/TT= XXXX (Mode, Target RPM or Target Temperature)
AT=XX. RPM= XXXX (Actual Temperature, Actual RPM)
To run this project locally, follow these steps to set up your environment and hardware.
- Mbed Studio or another Mbed-enabled IDE
- NUCLEO-F070RB Board
- External DC fan with tachometer output
- Rotary encoder
- LCD compatible with ST7066U
- Temperature sensor compatible with I2C interface
- Basic soldering and wiring tools
-
Clone the Repository:
git clone https://github.com/requiem002/ie_cw.git
-
Open the Project in Mbed Studio
- Launch MBED Studio
- Import the cloned folder as an MBED project.
-
Install Libraries:
- Ensure all required libraries are included in
mbed_app.jsonor imported as libraries.
- Ensure all required libraries are included in
-
Compile & Flash
- Connect the NUCLEO board via USB.
- Build the project in Mbed Studio.
- Drag and drop the compiled
.binfile onto the NUCLEO drive.
Once powered, the LCD will show the current mode. Use the push button to cycle through modes:
- OFF Mode: Fan is off.
- Closed-Loop Mode: Turn the rotary encoder to set a target RPM. The PID controller maintains this RPM.
- Open-Loop Mode: Turn the encoder to set a target RPM, but the duty cycle is determined by a predefined curve, not PID feedback.
- AUTO Mode: Turn the encoder to set a target temperature. The fan will speed up or slow down to maintain this temperature.
- CALIB Mode: The system automatically reduces duty cycle from 100% downwards, mapping RPM vs. duty cycle for future reference.
- Rotary Encoder: Adjust target RPM or temperature depending on the mode.
- Button: Cycle through the five modes.
- LCD & LEDs: Monitor current RPM, duty cycle, setpoint, and temperature. LED colors and LCD lines help visualize the system state. See LED Behaviour in System Overview for more information.
- Fan Not Spinning:
- Check power supply and ensure you’re not in OFF mode.
- Incorrect RPM Readings:
- Verify tachometer wiring. Make sure the pulse-per-revolution assumption matches your fan’s specifications.
- LCD Not Displaying:
- Confirm LCD pin connections and contrast settings.
- **Inaccurate performance with new fan **:
- Run the calibration mode to obtain and automatically set correct parameters for a new fan.
- Modes not changing when button pushed:
- Wait 1 second when in new mode for the mode to load or investigate push button signal.
- Add EEPROM storage for PID parameters and user preferences.
- Implement a menu system for switching modes and setting parameters via the encoder.
- Expand the temperature control to include hysteresis.
- Add fan fault detection and notifications.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the project_license. See LICENSE.txt for more information.
Saad Ahmed [sa2879@bath.ac.uk] Tom Hunter [th970@bath.ac.uk]
Project Link: https://github.com/requiem002/ie_cw
- Coursework Guidance: Thanks to Sanjae King and Professor Despina Moschou for providing the foundational materials and hardware schematics.
- Generative AI: Acknowledgments to ChatGPT by OpenAI, along with Claude Opus by Anthropic for code checking and guidance.
- Libraries Used:
LCD_ST7066Ulibrary by Luis Rodriguez [https://os.mbed.com/users/luisfrdr/code/LCD_ST7066U/]mRotaryEncoder-oslibrary by Karl Zweimüller [https://os.mbed.com/users/charly/code/mRotaryEncoder-os/]PIDlibrary adapted from Brett Beauregard's Arduino PID library.
This project was developed as part of a coursework activity to build an understanding of programming an embedded processor-based system using C.
