Controlling Fan Speed with Temperature-Based Logic in Embedded Systems
Mar 24, 2025 - ⧖ 4 minIn embedded systems, managing thermal performance is often critical for
maintaining reliability and efficiency. One common strategy involves
controlling the speed of cooling fans based on real-time temperature readings.
This post explores a Rust module built by me, fan-speed-control
, designed to
handle this task effectively.
Overview
The fan-speed-control
module is a lightweight, no_std
library written in
Rust. It provides a configurable controller for managing fan speed based on
temperature thresholds. It is a Implementation of a linear fan speed controller.
Key Features
- Configurable Parameters: The module allows users to define minimum and maximum fan speeds, along with temperature thresholds for turning the fan on, off, and reaching full speed.
- Temperature-Based Control: Fan speed is adjusted linearly based on temperature readings between defined thresholds.
- Spin-Up Logic: The controller includes a spin-up phase where the fan runs at maximum speed for a specified duration to overcome initial inertia.
Module Structure
The module consists of two main components: FanSpeedControlConfig
and FanSpeedControl
.
FanSpeedControlConfig
This struct holds the configuration parameters for the fan speed controller:
#[derive(Debug)]
pub struct FanSpeedControlConfig {
pub min_speed: u32,
pub max_speed: u32,
pub temp_on: f32,
pub temp_off: f32,
pub temp_full: f32,
pub spin_up_duration: embedded_time::duration::Seconds,
}
min_speed
: Minimum fan speed.max_speed
: Maximum fan speed.temp_on
: Temperature to turn on the fan.temp_off
: Temperature to turn off the fan.temp_full
: Temperature for full fan speed.spin_up_duration
: Duration to spin up the fan at maximum fan speed in seconds.
Pro Tip: You can use pwm duty cycles for min_speed and max_speed
FanSpeedControl
This struct represents the fan speed controller and includes methods for stepping the controller state machine with temperature readings and current time.
Operation Modes
- Off Mode: The fan is stopped. When the temperature rises above
temp_on
, the controller transitions to SpinUp mode. - SpinUp Mode: The fan runs at maximum speed for
spin_up_duration
seconds to overcome initial inertia. After this period, it transitions to Ramp mode. - Ramp Mode: The fan speed varies linearly with temperature between
min_speed
attemp_on
andmax_speed
attemp_full
. If the temperature falls belowtemp_off
, it returns to Off mode.
---
title: Fan controller states
---
stateDiagram-v2
[*] --> Off
Off --> SpinUp : Temperature is above on threshold
SpinUp --> Ramp : Spin up time has passed
Ramp --> Off : Temperature is below off threshold
The Math of Ramp mode
The linear speed algorithm employed in the fan-speed-control
module is a
straightforward yet effective method for adjusting fan speed based on
temperature readings. This algorithm operates in the Ramp mode, where the fan
speed increases linearly from a minimum speed at the temperature threshold for
turning the fan on (temp_on
) to a maximum speed at the temperature threshold
for full speed (temp_full
).
The algorithm calculates the fan speed using a linear equation of the form
speed = m * temperature + b
, where m
is the slope and b
is the intercept.
Both m
and b
are calculated by the specified FanSpeedControlConfig
:
let m = (max_speed - min_speed) / (temp_full - temp_on);
let b = min_speed - (m * temp_on);
This approach ensures a smooth and proportional response to temperature changes.
This linear approach provides a predictable and gradual adjustment of fan speed, helping to maintain stable thermal conditions without abrupt changes.
Example Usage
Here’s a simple example of how to use the FanSpeedControl
:
use fan_speed_control::{FanSpeedControlConfig, FanSpeedControl};
use embedded_time::{duration::Seconds, Instant, Clock};
use std_embedded_time::StandardClock;
let config = FanSpeedControlConfig {
min_speed: 20,
max_speed: 100,
temp_on: 40.0,
temp_off: 35.0,
temp_full: 60.0,
spin_up_duration: Seconds(2),
};
let mut controller = FanSpeedControl::new(config);
let clock = StandardClock::default();
let speed = controller.step(45.0, clock.try_now().unwrap());
Conclusion
The fan-speed-control
module provides a robust and flexible solution for
controlling fan speed in embedded systems. Whether you're working on a
microcontroller project or a larger embedded system, this module can help you
maintain optimal cooling performance.
For more details, you can explore the full source code and contribute to its development.