# STM32 based hysteretic PWM fan controller

This project is about a simple temperature regulator initialy designed to drive four fans inside a computer case, but I guess it can be used for a lot more applications. This controller is hysteretic, it means that for each fan it is possible to set a trigger temperature above which the fan will be driven be a high PWM ratio and beneath which it will be driven by a lower one.

## Prototype board

The prototype involves an STM32L031K6 nucleo-32 evaluation board mounted on another PCB that allows to drive the fans, light some LEDs... All the settings are passed through a serial communication with a small proprietary protocol that allows for instance to display the actual configuration, display current temperature, change the behaviour of the LEDs etc.

## Electrical/electronic connections and IOs

The board is either power through the SATA power connector (J3) or the the auxialliary power input connector (J6) with a 12V voltage source. Alternatively, it is possible to power the board directly through the embedded USB connector on the evaluation board but in this case it is not possible to power the fans which won't run under a voltage of 5V. Each fan is connected via a standard 3-pin 2.54mm pitch molex connector. The user can estimate the status of each channel with 4 red/green LEDs. The temperature sensor (LM35DZ from Ti) is able to measure any temperature in the 2°C to 150°C range. Finally a tactile switch is mounted and it is used for now to enable/disable the temperature regulator.

Here is a view of the connectors and IOs described above:

## Hysteretic control

Each channel is set with 4 parameters:

• Threshold temperature : Tthres
• Low state PWM duty cycle : Dlow
• High state PWM duty cycle : Dhigh
• Hysteresis value : Hys

The behaviour of the PWM channel controlling the fan is described in the chart below:

## AT command set

The settling of the board is performed through the USB connector using a serial terminal. Serial configuration is 115200bps, 8-bit of data, no parity and 1 stop byte. Each configuration frame must start with ":" (0x3A) and end with a carriage return (0x0D). They should follow this framing:

:<command>,<parameter1>,<parameter2>,<parameter3>,<...><CR>


The controller will responds to most of request with "OK" or "ERROR".

### SET

Allows to configure a pwm channel. This command responds with "OK" or "ERROR".

:SET,<channel>,<T_thres>,<D_min>,<D_max><CR>

• channel : channel identifier from 1 to 4
• T_thres : Threshold temperature in tenth of a celcius degree from 0 to 1000
• D_low : Low state PWM duty cycle from 0 to 100
• D_high : High state PWM duty cycle from 0 to 100

### TRACE

Displays the measured temperature on the terminal in tenth of a degree. The temperature is sent every 500ms until the user send a carriage return (0x0D).

:TRACE<CR>


### START

Allows the user to define the PWM duty cycle that is applied to every channel at the startup of the board. This command responds with "OK" or "ERROR".

:START,<D>,<duration><CR>

• D : Startup duty cycle from 0 to 100
• duration : startup duration in ms from 0 to 60000

### HYST

Allows the user to define the hysteresis value for each channel. This command responds with "OK" or "ERROR".

:HYST,<channel>,<hys><CR>

• channel : channel identifier from 1 to 4
• hys : hysteresis value in tenth of a degree from 5 to 50

### CONFIG

This command can be used to display an array containing the current configuration for all the channels. This command responds with the data followed by "OK" or "ERROR".

:CONFIG<CR>


Response format :

:CONFIG CH<n>: <T_thres>, <D_low>, <D_high>, <Hys>


Response example:

CONFIG CH1: 250, 0, 100, 10
CONFIG CH2: 250, 0, 100, 10
CONFIG CH3: 250, 0, 100, 10
CONFIG CH4: 250, 0, 100, 10
OK