Jump to content

FanControl, my take on a SpeedFan replacement

Here's version 1.3 of my ExternalFanControl.bat file.  To see what's new, see the ChangeLog near its top.  There's a new version, though... see next message.

@echo off
set BATNAME=ExternalFanControl
set BATVER=1.3
rem  Usage: ExternalFanControl [LoopDuration] [SIM]
rem     Loop duration is the frequency to read drive's temperature, in seconds (default 60).
rem     If SIM is specified, will simulate a randomly varying drive temperature.
rem  You should create a Windows Scheduler Task to trigger this .bat when Windows starts.
rem
rem  CHANGELOG:
rem  1.3 Creates the Logs folder if it doesn't exist.
rem      Begins by ending all external fan fancontrol tasks, in case one was already running.
rem      Added customizable constant for drive temperature S.M.A.R.T. attribute name reported by smartctl,
rem         in case the name isn't always Temperature_Celsius.
rem      Cleaned up the code, including making all names of constants UPPERCASE and all names of variables CamelCase.
rem  1.2 Changed DEBUG command-line parameter to SIM.
rem      Allows command-line parameters in any order.
rem      Expects the Task Scheduler tasks to be in Task Scheduler folder "FanControl tasks".
rem
rem  TODO:
rem
rem  CANCELED TODO (because experiment showed selftest doesn't significantly warm drive):
rem      Run selftests while drive is colder than temperature range.

REM ===============================================================================
rem IN THIS SECTION ARE SETTINGS YOU MUST CUSTOMIZE FOR YOUR SYSTEM:

rem  The volume label (without the colon) or device id of the external drive to be cooled:
   set "EXTERNALDRIVE=D"
rem  The ramdisk volume, or some other writeable location, for a temporary file:
   set "TMPDIR=R:"
rem  The folder where smartctl.exe is located:
   set "PROGDIR=C:\Smartmontools"
rem  The S.M.A.R.T. attribute name of the drive's temperature, as reported by smartctl:
   set "ATTRIBUTE=Temperature_Celsius"
rem  The folder where the temperature log will be written:
   set "LOGDIR=N:\FanControl\Logs"

rem  The folder in Windows Task Scheduler where you defined all the flat curve tasks:
   set "SCHEDULERFOLDER=\FanControl tasks\"
rem  The common prefix portion of each of the flat curve tasknames:
   set "TASKPREFIX=FanControl - External Fan - "
rem  The desired temperature range, in degrees Celsius, for the external drive:
   set /A "COLDESTTEMPERATURE=32, WARMESTTEMPERATURE=39"
rem  A FanControl task must exist for each degree in the above range of temperatures,
rem     with the taskname suffix matching the temperature, and another task must
rem     exist that has FULLSPEED as the suffix in its name.
rem  The corresponding FanControl copies should be configured to 0% at COLDESTTEMPERATURE, 
rem     100% (the FULLSPEED copy) when exceeding WARMESTTEMPERATURE, and monotonic in between.
rem  The tasks should have no automatic trigger; let this .bat start and stop them so only one at a time runs.
rem  The tasks must have highest privileges so that FanControl can control the motherboard's fan speed header.

REM ========= (end of customization section) ====================================

if not exist %LOGDIR%\NUL mkdir %LOGDIR%

set "FANTASKNAME=%SCHEDULERFOLDER%%TASKPREFIX%"

rem  Default parameters that command-line can override:
set LoopSeconds=60
set SimTemp=N

rem  Allow FanControl 5 seconds to gracefully exit when its task is ended:
set ENDSECONDS=5

rem  Process the command-line:
set /A "_Seconds=0"
if NOT [%1]==[] set /A "_Seconds+=%1"
if NOT [%2]==[] set /A "_Seconds+=%2"
if NOT [%3]==[] set /A "_Seconds+=%3"
if %_Seconds% GTR 0  set /A "LoopSeconds=_Seconds"
if [%1]==[SIM]  set SimTemp=Y
if [%2]==[SIM]  set SimTemp=Y
if [%3]==[SIM]  set SimTemp=Y

TITLE %BATNAME%_v%BATVER% [%COLDESTTEMPERATURE%C..%WARMESTTEMPERATURE%C] [%LoopSeconds% seconds] fan for %EXTERNALDRIVE%:
set "SNAPFILE=%TMPDIR%\%BATNAME%_%LoopSeconds%seconds.txt"
if exist %SNAPFILE%  del /Q %SNAPFILE%

set "SMARTCTL=%PROGDIR%\smartctl.exe"
if not exist "%SMARTCTL%" (
   echo Aborting: '%SMARTCTL%' not found.
   EXIT /B 1
)
rem  Embed the start date & time in the log filename:
set datetime=%date:~10,4%.%date:~4,2%.%date:~7,2%-%time:~0,2%%time:~3,2%%time:~6,2%
set datetime=%datetime: =0%
set "LOG=%LOGDIR%\%BATNAME%%BATVER%_%datetime%_[%LoopSeconds%_seconds].LOG"
echo Snapfile[%SNAPFILE%]
echo Log[%LOG%]
echo Date,Time, Celsius>> %LOG%

rem  In case an external fan FanControl task is already running, try to end all of them:
for /L %%G in (%COLDESTTEMPERATURE%, 1, %WARMESTTEMPERATURE%) do (
   SCHTASKS /End /TN "%FANTASKNAME%%%G"
)
SCHTASKS /End /TN "%FANTASKNAME%FULLSPEED"
rem  Wait a few seconds to allow tasks to end as gracefully as possible:
TIMEOUT /T %ENDSECONDS% >nul

setlocal enabledelayedexpansion

set /A "PrevTemp=999, PrevTask=999"

rem  INFINITE LOOP:
FOR /L %%G in (0,0,0) do (
   rem  Read the temperature of the external drive:
   for /f "delims=" %%H in ('%SMARTCTL% -A %EXTERNALDRIVE%: ^| findstr /R %ATTRIBUTE%' ) do set "line=%%H"
   set Celsius=!line:~87,2!
   if %SimTemp%==Y (
      rem  For testing, simulate temperature that randomly varies in [COLDESTTEMPERATURE-1 .. COLDESTTEMPERATURE+5] or 99C:
      for /F "tokens=1-4 delims=:." %%a in ("!time!") do set /A "RandDigit=(1%%d-100)%%10"
      if !RandDigit! LEQ 6  (
         set /A "Celsius=COLDESTTEMPERATURE+RandDigit-1"
      ) else (
         set /A "Celsius=99"
   )  )
   set Datestamp=!date:~4!
   set Timestamp=!time: =!
   echo !Datestamp! !Timestamp!   !Celsius! > %SNAPFILE%

   set /A "PauseTime=LoopSeconds"

   rem  If temperature changed, log the temperature and control the fan speed:
   if !Celsius! NEQ !PrevTemp! (
      echo !Datestamp!,!Timestamp!, !Celsius!>> %LOG%
      rem  Calculate which fan task is appropriate for the temperature:
      if !Celsius! LEQ %COLDESTTEMPERATURE% (
         set /A "FanTask=COLDESTTEMPERATURE"
      ) else (
         if !Celsius! GTR %WARMESTTEMPERATURE% (
            set "FanTask=FULLSPEED"
         ) else (
            set /A "FanTask=Celsius"
      )  )
      rem Check whether running fan task is the appropriate task, and if not, end running task and start appropriate task:
      if !FanTask! NEQ !PrevTask! (
         if !PrevTask! NEQ 999 (
            echo !date! !time!  Ending task "%FANTASKNAME%!PrevTask!"
            SCHTASKS /End /TN "%FANTASKNAME%!PrevTask!"
            rem  Wait a few seconds to allow FanControl task to end as gracefully as possible:
            TIMEOUT /T %ENDSECONDS% >nul
            set /A "PauseTime-=ENDSECONDS"
         )
         echo !date! !time!  Starting task "%FANTASKNAME%!FanTask!" !Celsius!C
         SCHTASKS /Run /TN "%FANTASKNAME%!FanTask!"
         set PrevTask=!FanTask!
      )
      set PrevTemp=!Celsius!
   )
   echo !Datestamp! !Timestamp!   !Celsius!C  task!FanTask!
   rem  Repeat the loop about once per minute, or whatever loop duration was specified in command-line:
   TIMEOUT /T !PauseTime! >nul
)

EXIT /B 0

 

Edited by Adrenalina
Version 1.3 is no longer the latest version of my .bat file..
Link to comment
Share on other sites

Link to post
Share on other sites

Below is version 1.4 of ExternalFanControl.bat.  See the ChangeLog near its top.  Note that there is now a second .bat file named setCONSTANTS.bat into which the customizable constants have been moved; that's now the .bat file you would need to edit to customize the constants for your hardware and your preferences.  The setCONSTANTS.bat file is below too.

 

Besides moving constants to a separate .bat file, the other change in 1.4 is that I shortened the names of the folder and the tasks in Windows Task Scheduler. (Those names are now defined in setCONSTANTS.bat, which you can edit if you prefer to name your tasks differently.)  Here's a screencapture of Windows Task Scheduler that shows the folder and fan tasks, in which you can see the shorter names.  Three tasks are running: the task for the copy of FanControl that controls the internal fans, the ExternalFanControl.bat task, and the task for the copy of FanControl that gets started when the external drive's temperature is 32C or below (which has a 0% flat curve, which I think is appropriate for a 32C hard drive temperature).

98578579_Fancontroltasksv1.4-WindowsTaskSchedulerscreencapture(16colors).thumb.png.374988e71d4304615c355776586806ae.png

 

First, here's ExternalFanControl.bat:

@echo off
set BATNAME=ExternalFanControl
set BATVER=1.4
rem  PURPOSE: To manipulate FanControl into controlling the speed of a fan based on the temperature of an external drive.
rem  USAGE: ExternalFanControl [LoopDuration] [SIM]
rem     Loop duration is the frequency to read drive's temperature, in seconds (default 60).
rem     If SIM is specified, will simulate a randomly varying drive temperature.
rem  You probably want to create a Windows Scheduler Task to trigger ExternalFanControl.bat
rem     each time Windows starts.
rem
rem  CHANGELOG:
rem  1.4 Moved constants customizations section into a new .bat file: setCONSTANTS.bat
rem      In setCONSTANTS.bat, shortened the names of the Windows Task Scheduler folder and tasks.
rem  1.3 Creates the Logs folder if it doesn't exist.
rem      Begins by ending all external fan fancontrol tasks, in case one was already running.
rem      Added customizable constant for drive temperature S.M.A.R.T. attribute name reported by smartctl,
rem         in case the name isn't always Temperature_Celsius.
rem      Cleaned up the code, including making all names of constants UPPERCASE and all names of variables CamelCase.
rem  1.2 Changed DEBUG command-line parameter to SIM.
rem      Allows command-line parameters in any order.
rem      Expects the Task Scheduler tasks to be in Task Scheduler folder "FanControl tasks".
rem
rem  TODO:
rem
rem  CANCELED TODO (because experiment showed selftest doesn't significantly warm drive):
rem      While drive is colder than temperature range, run selftests to warm up the drive.

rem  You need to customize the following .bat file to suit your hardware and your preferences.
call setCONSTANTS.bat

if not exist %LOGDIR%\NUL mkdir %LOGDIR%

set "FANTASKNAME=%SCHEDULERFOLDER%%TASKPREFIX%"

rem  Default parameters that command-line can override:
set LoopSeconds=60
set SimTemp=N

rem  Allow FanControl 5 seconds to gracefully exit when its task is ended:
set ENDSECONDS=5

rem  Process the command-line:
set /A "_Seconds=0"
if NOT [%1]==[] set /A "_Seconds+=%1"
if NOT [%2]==[] set /A "_Seconds+=%2"
if NOT [%3]==[] set /A "_Seconds+=%3"
if %_Seconds% GTR 0  set /A "LoopSeconds=_Seconds"
if [%1]==[SIM]  set SimTemp=Y
if [%2]==[SIM]  set SimTemp=Y
if [%3]==[SIM]  set SimTemp=Y

TITLE %BATNAME%_v%BATVER% [%COLDESTTEMPERATURE%C..%WARMESTTEMPERATURE%C] [%LoopSeconds% seconds] fan for %EXTERNALDRIVE%:
set "SNAPFILE=%TMPDIR%\%BATNAME%_%LoopSeconds%seconds.txt"
if exist %SNAPFILE%  del /Q %SNAPFILE%

set "SMARTCTL=%PROGDIR%\smartctl.exe"
if not exist "%SMARTCTL%" (
   echo Aborting: '%SMARTCTL%' not found.
   EXIT /B 1
)
rem  Embed the start date & time in the log filename:
set datetime=%date:~10,4%.%date:~4,2%.%date:~7,2%-%time:~0,2%%time:~3,2%%time:~6,2%
set datetime=%datetime: =0%
set "LOG=%LOGDIR%\%BATNAME%%BATVER%_%datetime%_[%LoopSeconds%_seconds].LOG"
echo Snapfile[%SNAPFILE%]
echo Log[%LOG%]
echo Date,Time, Celsius>> %LOG%

rem  In case an external fan FanControl task is already running, try to end all of them:
for /L %%G in (%COLDESTTEMPERATURE%, 1, %WARMESTTEMPERATURE%) do (
   SCHTASKS /End /TN "%FANTASKNAME%%%G"
)
SCHTASKS /End /TN "%FANTASKNAME%FULLSPEED"
rem  Wait a few seconds to allow tasks to end as gracefully as possible:
TIMEOUT /T %ENDSECONDS% >nul

setlocal enabledelayedexpansion

set /A "PrevTemp=999, PrevTask=999"

rem  INFINITE LOOP:
FOR /L %%G in (0,0,0) do (
   rem  Read the temperature of the external drive:
   for /f "delims=" %%H in ('%SMARTCTL% -A %EXTERNALDRIVE%: ^| findstr /R %ATTRIBUTE%' ) do set "line=%%H"
   set Celsius=!line:~87,2!
   if %SimTemp%==Y (
      rem  For testing, simulate temperature that randomly varies in [COLDESTTEMPERATURE-1 .. COLDESTTEMPERATURE+5] or 99C:
      for /F "tokens=1-4 delims=:." %%a in ("!time!") do set /A "RandDigit=(1%%d-100)%%10"
      if !RandDigit! LEQ 6  (
         set /A "Celsius=COLDESTTEMPERATURE+RandDigit-1"
      ) else (
         set /A "Celsius=99"
   )  )
   set Datestamp=!date:~4!
   set Timestamp=!time: =!
   echo !Datestamp! !Timestamp!   !Celsius! > %SNAPFILE%

   set /A "PauseTime=LoopSeconds"

   rem  If temperature changed, log the temperature and control the fan speed:
   if !Celsius! NEQ !PrevTemp! (
      echo !Datestamp!,!Timestamp!, !Celsius!>> %LOG%
      rem  Calculate which fan task is appropriate for the temperature:
      if !Celsius! LEQ %COLDESTTEMPERATURE% (
         set /A "FanTask=COLDESTTEMPERATURE"
      ) else (
         if !Celsius! GTR %WARMESTTEMPERATURE% (
            set "FanTask=FULLSPEED"
         ) else (
            set /A "FanTask=Celsius"
      )  )
      rem Check whether running fan task is the appropriate task, and if not, end running task and start appropriate task:
      if !FanTask! NEQ !PrevTask! (
         if !PrevTask! NEQ 999 (
            echo !date! !time!  Ending task "%FANTASKNAME%!PrevTask!"
            SCHTASKS /End /TN "%FANTASKNAME%!PrevTask!"
            rem  Wait a few seconds to allow FanControl task to end as gracefully as possible:
            TIMEOUT /T %ENDSECONDS% >nul
            set /A "PauseTime-=ENDSECONDS"
         )
         echo !date! !time!  Starting task "%FANTASKNAME%!FanTask!" !Celsius!C
         SCHTASKS /Run /TN "%FANTASKNAME%!FanTask!"
         set PrevTask=!FanTask!
      )
      set PrevTemp=!Celsius!
   )
   echo !Datestamp! !Timestamp!   !Celsius!C  task!FanTask!
   rem  Repeat the loop about once per minute, or whatever loop duration was specified in command-line:
   TIMEOUT /T !PauseTime! >nul
)

EXIT /B 0

Finally, here's setCONSTANTS.bat:

@echo off
rem  setCONSTANTS.bat is called by ExternalFanControl.bat, and sets custom constants
rem  that define the drive whose temperature is to be monitored, some folder names, etc.
rem  It's also called by FanTasksStatus.bat which needs some of these constants too.
rem  Because these constants are needed by both ExternalFanControl and FanTasksStatus,
rem  their definitions were placed in setCONSTANTS.bat to avoid redundancy.
rem  YOU NEED TO EDIT THE FOLLOWING CONSTANTS TO MATCH YOUR HARDWARE AND PREFERENCES.

rem  For explanations of the following constants, see the NOTES section below.

set "EXTERNALDRIVE=D"
set "TMPDIR=R:"
set "PROGDIR=C:\Smartmontools"
set "ATTRIBUTE=Temperature_Celsius"
set "LOGDIR=N:\FanControl\Logs"
set /A "COLDESTTEMPERATURE=32, WARMESTTEMPERATURE=39"
set "TASKPREFIX=External Fan - "
set "SCHEDULERFOLDER=\FanControl\"

EXIT /B
=======================================

NOTES:

EXTERNALDRIVE is the volume label (without the colon) or device id of 
the external drive to be cooled.  If the external drive has no volume label, 
you can use smartctl.exe to identify its device id.  The device id might 
look something like /dev/sda.

TMPDIR is the ramdisk volume (or some other writeable location) where a temporary
file will be created and periodically updated by ExternalFanControl.bat.   If you
run ExternalFanControl.bat as a hidden task, one way to know it's running is to
look at the temporary file's timestamp.

PROGDIR is the folder where smartctl.exe is located.  smartctl.exe is a utility
that comes with Smartmontools (which is free) and is needed to read the temperature
of the USB-connected external drive... which FanControl cannot do because FanControl
relies on a third party library that doesn't yet know how to do USB pass-through 
of S.M.A.R.T. attributes.

ATTRIBUTE is the S.M.A.R.T. attribute name of the drive's temperature, as reported 
by smartctl.  Other SMART monitor software, for example CrystalDiskInfo, may display
a different name, but what's relevant is the name reported by smartctl.

LOGDIR is the folder where you want the temperature log to be written.  If the folder
doesn't yet exist, ExternalFanControl.bat will create it.

COLDESTTEMPERATURE and WARMESTTEMPERATURE define the desired temperature range,
in degrees Celsius, for the external drive.  If the drive temperature is at
or below COLDESTTEMPERATURE, you want the fan speed to be 0%.  If the drive
temperature is above WARMESTTEMPERATURE, you want the fan speed to be 100%.
For temperatures in between, you want the fan speed to be in between, and
you want those speeds to increase monotonically with temperature; for example
10% at 1+COLDESTTEMPERATURE, 20% at 2+COLDESTTEMPERATURE, etc.

TASKPREFIX is the common beginning portion of the Windows Task Scheduler tasknames
of the external fan FanControl flat curve tasks that you need to define, and
SCHEDULERFOLDER is the folder in Windows Task Scheduler where you place those
tasks.  A task must be defined for each degree in the desired temperature range
with the ending portion of each taskname matching the temperature, and another
task must exist that has FULLSPEED as the ending portion of its name.  For each
task you must have a corresponding copy of FanControl, each copy in its own folder,
and each copy configured with a flat curve for the fan speed appropriate to the
temperature. Each task must be defined to start the corresponding copy of FanControl.
As mentioned above, the FanControl copy that gets started for COLDESTTEMPERATURE
should be configured with a 0% flat curve, the copy that gets started when the
temperature exceeds WARMESTTEMPERATURE should be configured with a 100% flat curve,
etc.  The tasks should have no trigger defined; let ExternalFanControl.bat start
and stop them so only one external fan FanControl at a time runs. The tasks must
be defined with "highest privilege" because FanControl needs to have Admin rights
in order to control the motherboard's fan headers.

[End of Notes]

 

Link to comment
Share on other sites

Link to post
Share on other sites

@Adrenalina 

 

If you don't mind, would you open a new thread regarding your script? It kinda bloats this one, and I would like to keep this one for general questions and discussion. Thanks.

Link to comment
Share on other sites

Link to post
Share on other sites

@Rem0o @Adrenalina I realise you just asked for the scripts to move, but... Could such a script be used to link PC power profile changes to the change in fan speed profile? (e.g, silent fan profile that switches to low power profile with lower max CPU etc.)

Link to comment
Share on other sites

Link to post
Share on other sites

9 hours ago, yfbcjw said:

@Rem0o @Adrenalina I realise you just asked for the scripts to move, but... Could such a script be used to link PC power profile changes to the change in fan speed profile? (e.g, silent fan profile that switches to low power profile with lower max CPU etc.)

Assuming my .bat file continues to work without problems, then in principle yes.  A script can stop & start different FanControl tasks for reasons other than the temperature of a component.  A .bat file could read the active power scheme by using the "powercfg /getactivescheme" command and could use that information to stop & start FanControl tasks.

 

Or the "powercfg /setactive" command could be used to change the active power scheme, if this is what you meant.

 

If you mean trying to detect which FanControl configuration file is active, and using that information to switch to a different power scheme, then I think yes.  It appears that FanControl stores the name of its currently active configuration in the CACHE file, so a script could frequently check whether the CACHE file has been modified and, if so, could read the name of the active configuration and respond accordingly.

Edited by Adrenalina
Added paragraph about FanControl storing the current config name in CACHE
Link to comment
Share on other sites

Link to post
Share on other sites

9 hours ago, Rem0o said:

@Adrenalina 

 

If you don't mind, would you open a new thread regarding your script? It kinda bloats this one, and I would like to keep this one for general questions and discussion. Thanks.

I'll stop posting new versions of my External Fan Control project here.  If I create a new thread, I'll post a link to that thread here.

 

Would it be okay if I occasionally post new lines of the ChangeLog here?  For example:

v1.5 Moved the few remaining definitions of constants and default parameters closer to the top.

Changed findstr /R to findstr /C just in case smartctl's temperature attribute name is multiple words for some user's drive.

 

I think my project is finished with v1.5, so I don't expect to start a new thread.  Although it would be nice to have a companion .bat that automates the creation of Windows Task Scheduler tasks and copies of FanControl, I don't have enough incentive.

Link to comment
Share on other sites

Link to post
Share on other sites

8 hours ago, Adrenalina said:

Would it be okay if I occasionally post new lines of the ChangeLog here?

Well not really. As I said, I want to keep the discussions here specific to fan control itself, with feedback and stuff. I really think you should start your own thing, be it a Github repo, a new thread or whatever, but please don't hijack this one. Thanks.

Link to comment
Share on other sites

Link to post
Share on other sites

Update 35

 

  • Sub-1% command step
    • Command step can now be sub-1% values for even slower steps
  • Fixed single fan matching
    • Automatic fan matching for a single fan would do it for all the fans
  • Fixed a bug with mix fan curve when moving cards
    • This one was kind of subtle. When you had a mixed card with 2 selected fan curves, if you moved one of these curves cards, it would remove it from the mixed curve.
  • UI styling tweaks
    • Unified card styling, dialog buttons color and more significant "Ok" button labels.
Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, Rem0o said:

Well not really. As I said, I want to keep the discussions here specific to fan control itself, with feedback and stuff. I really think you should start your own thing, be it a Github repo, a new thread or whatever, but please don't hijack this one. Thanks.

As you wish.  I can see how my numerous posts in the past few days might be considered hijacking (especially the posting of three versions of the .bat file in two days).  My goal was to increase FanControl's value to other users.

Link to comment
Share on other sites

Link to post
Share on other sites

I just saw the new sub-1% values: thank you for improving FanControl!

Meanwhile I still report on my config (Asus z170 pro gaming) a misbehaviour while coming back from hibernate as well as a new thing which occurs randomly maximum twice a month:

the CPU fan (without any reason) spins suddenly at max speed and then decreases to the RPM it should be. The way it does that (the "tempo)" is exactly the one during the bios boot time, when you turn on the computer.

It is quite recent, but I cannot say that FanControl has something to do with this

Link to comment
Share on other sites

Link to post
Share on other sites

@Rem0o

Thanks a lot for your program! Going from Win 7 on an old CPU to Win 10 with a z490 board and losing SpeedFan compatibility let me search for an alternative.

Got my PC silent and cooled, thanks to you.

 

However I would like to request a feature that would make my life a lot easier but I have no idea how much effort it would take to code. All I'd need would be 3 steps that trigger/go up instantly when the CPU hits a certain temperature but not go lower until reaching another certain temperature, not being time related.

 

For example:
35% up until 75°c / 85% up until 83°c / 100% when above
100% until below 75°c / 85% until below 60°c / 35% when below

 

I tried to achieve this with response times and hysteresis, even mixing graphs with different hysteresis but I either end up with not consistent fan speeds or my CPU having temperature spikes if a bad combinations of temperature changes happens.

 

Or maybe I'm just stupid...  So I'll now make a longer write up but it's not about the feature, but about my exact case so feel free to ignore it.

 

So I'm gonna post my 2 current graph curves:

Graphs are mixed = Max

 

1. Graph:

Hysteresis = 15°c, Response time = 1

2 points: 75°c = 35%, 76°c = 85%

 

2. Graph:

Hysteresis = 30°c, Response time = 1

2 points: 83°c = 0%, 84°c = 100%

 

Last night I had a temperature spike from 72° to 94°, while the fans jumped from 35% to 100% but it wasn't quick enough.

The problem was that the temperature went like this:

72° (35%) -> 83° (85%) -> 71° (35%) -> 94° (100%)

 

What I don't get is with hysteresis at 15°, why got the 1. Graph triggered from 72° to 83° and why dropped it down to 35% when going down to 71°?

 

Anyway, I appreciate any help I can get. If it's just how it is I guess I'll have to find a way to change the config for every cpu intensive game or program at launch and back when I quit it.

 

Thanks in advance,

Rasmus

 

PS: 10600k with a pretty hot & dampened case. Old 2600k was fine but this new i5 goes up and down in temperature a lot faster... Not willing to buy a better case just now though

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, RaazP said:

@Rem0o

Thanks a lot for your program! Going from Win 7 on an old CPU to Win 10 with a z490 board and losing SpeedFan compatibility let me search for an alternative.

Got my PC silent and cooled, thanks to you.

 

However I would like to request a feature that would make my life a lot easier but I have no idea how much effort it would take to code. All I'd need would be 3 steps that trigger/go up instantly when the CPU hits a certain temperature but not go lower until reaching another certain temperature, not being time related.

 

For example:
35% up until 75°c / 85% up until 83°c / 100% when above
100% until below 75°c / 85% until below 60°c / 35% when below

 

I tried to achieve this with response times and hysteresis, even mixing graphs with different hysteresis but I either end up with not consistent fan speeds or my CPU having temperature spikes if a bad combinations of temperature changes happens.

 

Or maybe I'm just stupid...  So I'll now make a longer write up but it's not about the feature, but about my exact case so feel free to ignore it.

 

So I'm gonna post my 2 current graph curves:

Graphs are mixed = Max

 

1. Graph:

Hysteresis = 15°c, Response time = 1

2 points: 75°c = 35%, 76°c = 85%

 

2. Graph:

Hysteresis = 30°c, Response time = 1

2 points: 83°c = 0%, 84°c = 100%

 

Last night I had a temperature spike from 72° to 94°, while the fans jumped from 35% to 100% but it wasn't quick enough.

The problem was that the temperature went like this:

72° (35%) -> 83° (85%) -> 71° (35%) -> 94° (100%)

 

What I don't get is with hysteresis at 15°, why got the 1. Graph triggered from 72° to 83° and why dropped it down to 35% when going down to 71°?

 

Anyway, I appreciate any help I can get. If it's just how it is I guess I'll have to find a way to change the config for every cpu intensive game or program at launch and back when I quit it.

 

Thanks in advance,

Rasmus

 

PS: 10600k with a pretty hot & dampened case. Old 2600k was fine but this new i5 goes up and down in temperature a lot faster... Not willing to buy a better case just now though

Lots of things here. 

1) I feel like what you are trying to do is kinda weird. Why have "plateau" like this instead of a smooth ramp up/down? And why have a different ramp up/down sequence? Isn't that overly complicated for pretty much nothing? If you combine a smooth ramp with appropriate hysteresis and response time, you'll have a much better experience in the long run.

 

2) You seem to want to have "burst cooling" when the CPU hits a high number.  Sadly, when you see the number, it's probably already too late. There is up to a second of lag between the actual temp and when the program sees it / act on it, that's just the nature of polling the data. If your CPU hits too high of a temp spike for you, you won't fix your problem with fan curves. You probably need a bigger cooler, better thermal compound, better contact and so on. The time between "Increasing the fan speed" and "the cpu gets cooler"  is wayyyyyy slower than you think, much slower than your CPU ramps up and down in load and power usage. Think of fan speeds as a slow but smooth control of temperature over a long period of time. It manages the average temperature over time, not the peaks.

 

3) Your scenario: 72° (35%) -> 83° (85%) -> 71° (35%) -> 94° (100%) 
If it the did hit the 35% after the 85%, then your sequence is wrong. I could show you the line of code that does the hysteresis and this exact scenario is impossible AFAIK. When the fan speed changes ( let say the first 35%), it records the temperature at which it changed speed, here 72 deg. It won't change fan speed again until: abs(new_temperature - 72) >= 15 for more than "Response time" consecutive seconds, so here 1 second. 

 

I guess this whole thing is a matter of cooling philosophy. Obviously I coded this utility with a bias of the knowledge I got regarding cooling, thermodynamics and my overall preference for simplicity. If you ain't sharing the same philosophy, then I can understand why the software may feel off for you.

Link to comment
Share on other sites

Link to post
Share on other sites

4 hours ago, Rem0o said:

Lots of things here. 

1) I feel like what you are trying to do is kinda weird. Why have "plateau" like this instead of a smooth ramp up/down? And why have a different ramp up/down sequence? Isn't that overly complicated for pretty much nothing? If you combine a smooth ramp with appropriate hysteresis and response time, you'll have a much better experience in the long run.

 

2) You seem to want to have "burst cooling" when the CPU hits a high number.  Sadly, when you see the number, it's probably already too late. There is up to a second of lag between the actual temp and when the program sees it / act on it, that's just the nature of polling the data. If your CPU hits too high of a temp spike for you, you won't fix your problem with fan curves. You probably need a bigger cooler, better thermal compound, better contact and so on. The time between "Increasing the fan speed" and "the cpu gets cooler"  is wayyyyyy slower than you think, much slower than your CPU ramps up and down in load and power usage. Think of fan speeds as a slow but smooth control of temperature over a long period of time. It manages the average temperature over time, not the peaks.

 

3) Your scenario: 72° (35%) -> 83° (85%) -> 71° (35%) -> 94° (100%) 
If it the did hit the 35% after the 85%, then your sequence is wrong. I could show you the line of code that does the hysteresis and this exact scenario is impossible AFAIK. When the fan speed changes ( let say the first 35%), it records the temperature at which it changed speed, here 72 deg. It won't change fan speed again until: abs(new_temperature - 72) >= 15 for more than "Response time" consecutive seconds, so here 1 second. 

 

I guess this whole thing is a matter of cooling philosophy. Obviously I coded this utility with a bias of the knowledge I got regarding cooling, thermodynamics and my overall preference for simplicity. If you ain't sharing the same philosophy, then I can understand why the software may feel off for you.

Hi,

oh wow, thanks for the detailed reply!

Guess I'll try to make a linear fan curve and see if it annoys me or works well.

It could all be solved by putting the response time higher to ignore peaks. But not ignoring peaks above 80°c would also be needed.

Maybe mix a linear graph with a 5s response time and high hysteresis with a graph that triggers above 80° (0 hysteresis and 1s response time)?

 

Anyway, long post again, sorry.. Hope you find it interesting to hear my "weird thoughts" so they may become a bit less weird for your perspective. Btw I'm halfway through my engineering bachelor so while ofc still beeing a noob, I have a basic understanding of the things you mentioned. Or if you think I have not, then feel free to tell me straight up so I'll learn.

 

To 1)

After your post I understand where you're coming from. Must look weird from your perspective. What I want to achieve is basically a constant fan noise for my 3 different use cases without short load peaks (if below 80°c) increasing the fans at all:

 

1. Desktop/Office stuff: CPU is most of the time at about 45°c, barely any load. But when I load an excel sheet, the temperature will peak up to 70° for 1-5 seconds, not really higher so I'd like my fans to stick at the 35%.

Only if something odd is happening and increasing the CPU load a lot, I'd like the fans to go up, of course.

 

2. Generic gaming: most of my games, mostly racing simulations won't max out the cpu.
At about 70% fan level, the cpu will vary between 60-80°c. So I'd like my fans to stick to the constant level of 70%. Not dropping down when I'm in the pitbox and the cpu cools down to 62°c  but also not ramp up for a short moment during fights with multiple cars (probably around 75°c).

 

3. Really stressing the cpu: when I'm rendering a video or playing a bit of Assassin's Creed, running around in a big city, the CPU might hit more than 80°c. Still varying between 65-84°c but anyway, constantly hitting high temperatures.

So I'd like my fans to stick at 100% all the time I'm in that big city or rendering the video.

And only lowering the fan speeds when the cpu will stay at a lower temperature.

 

Probably still kinda weird how I'm approaching this but in SpeedFan with the old 2600k it worked exactly like this. Might've been weird too but it worked and I had a very constant noise level depending on what I did.

 

To 2)

Probably enough said about this in 1): I don't want burst cooling, quite the opposite. I want my fans so stick at a certain level, if an application will frequently heat up the CPU above a certain temperature. Like "okay, if that game heats up the CPU to this level: Stick to a higher level until the situation really changes (cpu temperature going down a LOT).".

Just a note: the 94° won't happen with fan speeds being in "level 2" (85%). Thks high peak only happened because the fan level dropped before (for whatever reason..). 

I know you can't burst cool like that. The cpu will heat up way too quickly. 

 

To 3)

I really wondered about this happening too.. Probably down to afterburner/rtss being at 500ms refresh cycle, showing the peak. 

I tried to replicate and test my fan curves with the kombustor cpu burner and cinebench at different amounts of rendering threads. I see this little dot on the curves (very nice btw!) and depending on how I set the plateaus, the dot will stick at different points.

 

Example hysteresis of 20°, below 70°c = 35%, then 100%. The dot might stay be at the 50°c point. Then the temperature goes up to 70°c and the fan level goes up.

Then the temperature goes up to 89°c and drops down to 69°c. The fan level will go down to 35% and the "dot" will be at 69°c.

Now the temperatures need to go up to 89°c instead of 70°c for the fan level to change.

 

Anyway, I apologise for so much text! It seems that with the current functionality of FanControl, I should simply use a linear fan level graph and keep it from fluctuating too much via response time and hysteresis.

 

My approach would be kinda simple though I guess. I'm only able to code very basic stuff but for my needs the fan code would probably only need some if/else combinations for two cases: upwards or downwards cpu temperature change:

(rough coding. I know there's a lot more needed... I'm a noob at coding but it might give you an idea?)

Spoiler

// First refresh cycle without a cpu_old value

if ( cpu_temperature <= 75° ) {
    fan_level = 35%;
} else {
    fan_level = 100%;
}

cpu_old = cpu_temperature;


// All refresh cycles after that

cpu_now = cpu_temperature;

    // Upwards
if ( cpu_old <= cpu_now ) { 

    if ( cpu_now <= 75° ) {
        fan_level = 35%;
    } else if ( cpu_now <= 85° ) {
        fan_level = 80%;
    } else {
        fan_level = 100%;
    }
    // Downwards
} else if (cpu_old >= cpu_now ) { 

    if ( cpu_now <= 70° ) {
        fan_level = 80%;
    } else if ( cpu_now <= 55° ) {
        fan_level = 35%;
    }
    // Failsafe?
} else {
    fan_level = 100%;
}

cpu_old = cpu_now;

About my cooling:

- Cooler Master silencio 550

- Front: be quiet silent wings 3, 140mm

- Rear: silent wings 120mm

- CPU: Thermalright Le Grand Macho RT

 

The case is really bad... And the 10600k is a lot hotter than the 2600k, although that ran at 4.4 GHz all-core.

Link to comment
Share on other sites

Link to post
Share on other sites

On 6/21/2020 at 10:10 PM, Rem0o said:

According to this review: https://www.tweaktown.com/reviews/8377/gigabyte-z370-aorus-gaming-7-motherboard-review/index4.html, you got a IT8795E for fan control, which is not mapped specifically from the ITE chip list in OpenhardwareMonitor. You thus got a "generic" support for it.
image.png.381d4bebfc1e01be236b65a3c2a24372.png
 

Me again. I downloaded Argus Monitor free trial just for testing and it controls both fans normally (the only problem that I encountered it's that I can't make it stop fans, unlike your software. Argus here only goes to 5% minimum).

 

I don't know if this helps you to support my mobo for FanControl but in Argus it shows 2 different fan control chips:

spacer.png

 

If you could make FC compatible with both chips like Argus it would be amazing, because only Fancontrol can stop fans here, the ones that I'm able to control through it, of course.

Link to comment
Share on other sites

Link to post
Share on other sites

RaazP wrote: "I don't want burst cooling, quite the opposite. I want my fans to stick at a certain level, if an application will frequently heat up the CPU above a certain temperature."

 

Perhaps RaazP could achieve his goal if FanControl were enhanced to provide a second {hysteresis,responsetime} pair in each curve: one pair for rising and the other for falling. (Similar to the request by several users who have asked for two stepsizes in each fan control: one stepsize for rising steps and the other for falling steps.)  RaazP could then set a large hysteresis and a large response time in the pair that applies to falling cpu temperatures, to prevent the fan speed from decreasing until the cpu temperature has a large decrease.

 

FanControl might need to provide "slippery slope" (a.k.a. "low sliding friction") too, to prevent a combination of large hysteresis and small stepsize from causing the fan speed to get stuck partway along the curve before getting close to the target speed.  In other words, hysteresis would prevent the fan speed from taking a step when temperature has changed only a small amount, but once the fan speed takes a step, the slippery slope would cause fan speed to continue to take steps regardless of the hysteresis setting until the fan speed target is reached. (I'm assuming FanControl doesn't already implement slippery slope.  I haven't experimented to see whether it already does.)

 

I expect the code to implement the second {hysteresis,responsetime} pair would be simple, and there's plenty of display room available in the user interface for the second pair since it would be displayed only in the popup that appears when the user clicks the curve's Edit button.

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, Adrenalina said:

FanControl might need to provide "slippery slope" (a.k.a. "low sliding friction") too, to prevent a combination of large hysteresis and small stepsize from causing the fan speed to get stuck partway along the curve before getting close to the target speed.  In other words, hysteresis would prevent the fan speed from taking a step when temperature has changed only a small amount, but once the fan speed takes a step, the slippery slope would cause fan speed to continue to take steps regardless of the hysteresis setting until the fan speed target is reached. (I'm assuming FanControl doesn't already implement slippery slope.  I haven't experimented to see whether it already does.)

Hysteresis is already ignored at the bounds on the linear curve card, but I noticed it ain't in the graph card. Will fix.

Link to comment
Share on other sites

Link to post
Share on other sites

Just to report back:

 

Thanks for telling me that my approach was "weird". I thought about it for a while..

 

Thought I'd try the different approach then and it runs nicely as far as I can tell from only 2 days.

One graph (gonna transfer this into just a linear one):

flat at 35% until 50°c, going up in a straight line to 100% at 83°c.

10°c Hysteresis, 10s response time

 

Second graph:

flat at 0% until 85°c, then 100% at 86°c.

4°c Hyst, 1s response time

 

Mixed into a Max mix.

 

I know, still pretty weird for you probably but I found out that my cooler is big enough to passively cool my CPU long enough to sub 90°c that the second graph is quick enough if I get 100% load on all cores from complete idle.

Which is more a fail safe.. Apart from doing a benchmark out of idle, there's no program I'm using that wouldn't cause some load before maxing out.

Once the slow curve responses, the temperature will always be okay.

 

Overall the fan speed history (openhardwaremonitor for 24h logging) looks very nice and I didn't get annoyed get by ramping up/down fans.

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, RaazP said:

One graph (gonna transfer this into just a linear one):

flat at 35% until 50°c, going up in a straight line to 100% at 83°c.

10°c Hysteresis, 10s response time

 

Second graph:

flat at 0% until 85°c, then 100% at 86°c.

4°c Hyst, 1s response time

 

Mixed into a Max mix.

What's the use for that second graph in your mix? When the temp is at 83, the first graph will already max the mixed curve to 100%.
Or is it that since the 2nd graph is much faster (1s vs 10s), you get a fast response at that specific threshold, but for the rest of the temperature range, the 2nd graph goes to 0, so the mix curve switches to the 1st graph, which is a much slower/smoother response? If that is the case, that's very smart! You get the fast threshold ("burst") effect for a very high specific temp, and a smooth linear one for the rest of the range.  Never thought of doing that, very nice!

 

In other words, instead of mixing different sensors, you are mixing response time depending on the temperature.

Link to comment
Share on other sites

Link to post
Share on other sites

21 hours ago, Rem0o said:

Hysteresis is already ignored at the bounds on the linear curve card, but I noticed it ain't in the graph card. Will fix.

 

That boundary behavior doesn't sound like the concern I have about the possible need for "slippery slope" behavior.  On March 21 you released a version update that introduced the improved boundary behavior, and your message about it said: "I noticed sometime the linear fan curve would not go to its idle state (minimum) or full load (maximum) state since the hysteresis would prevent it. This is annoying if your minimum fan speed is 0% since it prevents it to stop. To fix that, the hysteresis (not the response time) is now ignored at the limits so the fan curve will "snap" to its minimum or maximum bound when near it." 

 

A target speed is not necessarily a minimum or maximum bound.  My concern is that large hysteresis might make the fan speed get stuck many steps away from the desired target speed, even though the fan speed had been stepping toward the target speed and hadn't yet settled on a speed.

 

Here's an example to illustrate: 

  1. Suppose the cpu fan control has stepsize 5% and is connected to a curve with temperature source = cpu, hysteresis = 15C, response time = 1 second, and linear curve 25%@30C to 100%@60C.  Note that the curve speed at 50C is 75% and at 55C is 87.5%.
  2. Suppose the cpu jumps from 30C to 50C in less than a second.  Since the change exceeds the hysteresis, FanControl calculates the target speed is now 75% and begins to increase the fan speed in 5% steps.
  3. After 5 steps, suppose the cpu temperature now increases further, from 50C to 55C.  The fan speed has reached 50% (25% + 5 steps).  The curve speed at 55C is 87.5%.  Since the 5C increase is less than the hysteresis, will the hysteresis prevent FanControl from adjusting the target speed from 75% to 87.5%?  Will the fan speed get stuck at 75%?

I think hysteresis should make the speed stick at 75% only if the speed had already reached 75%.  The purpose of hysteresis is stability, and while the speed is still rising toward 75% it's not yet stable.  FanControl should continue stepping the speed up, but toward the new target of 87.5%.  Is this what FanControl already does?

 

Here are two related examples:

 

Same as above example except that in #3 the cpu temperature decreases from 50C to 45C.  The curve speed at 45C is 62.5%.  Since the speed is at 50% and rising, FanControl should continue stepping the speed up, but toward the new 62.5% target.

 

Same as above example except that in #3 the cpu temperature decreases from 50C to 36C.  The curve speed at 36C is 40%.  Since the fan speed is above 40% and rising, and the 14C temperature drop is less than the 15C hysteresis, it might be considered reasonable for the hysteresis to make the fan speed stick where it is (50%) rather than reverse direction.  Or, it might be considered reasonable to start stepping the speed down toward 40% since rising means not yet stable or settled.  I have no opinion yet about which of these two alternatives is more desirable... and perhaps there's a third alternative that's better than both (but probably more complex).

Link to comment
Share on other sites

Link to post
Share on other sites

Below is a screencapture of FanControl that appears to show a bug.  In the curve editor window, you can see the curve named "E: hard drive" has a target fan speed of 74% at 39C.  The current temperature is 39C, but the curve (shown at the bottom left) and the fan control (not shown, behind the curve editor window; note that it has a stepsize of 1%) are stuck at 67%.955320493_FanControlscreencaptureshowingfanspeedstuckawayfromcurvespeed(16colorslightened).thumb.png.3d1ad4df2449246b3db2e9ebab7512da.png

Edited by Adrenalina
Improved the clarity of my description, and to note the 1% stepsize.
Link to comment
Share on other sites

Link to post
Share on other sites

I have a theory that would explain the FanControl behavior shown in my most recent message, where the fan speed is stuck at 67% when the curve calls for 74%.  It's like the frog in a pot of water that's being brought very slowly to a boil.  The temperature rise is so gradual that the frog never responds.  In this case, the stuck speed could be due to the hysteresis, which is intended to mute fan speed change responses to small changes of temperature.  Unfortunately, those small temperature changes can add up over time.  Could FanControl's non-response due to hysteresis allow computer parts to fry?

 

In the "E: hard drive" curve, 38C corresponds to 67% fan speed.  My theory is that the temperature of drive E: increased gradually from 38C to 39C over a long period of time, and that although FanControl displays temperatures as integers, it internally keeps track to within a fraction of a degree, which is smaller than the 1C hysteresis.  When the temperature rose from 38C to 38.5C, this was smaller than the 1C hysteresis, so FanControl left the fan speed at 67%.  When the temperature later rose from 38.5C to 39C, this again was smaller than the hysteresis, so FanControl again left the speed at 67%.

 

Assuming my explanation is correct, in the current version of FanControl there's only one workaround that I see that can guarantee components won't get much hotter than desired: the user must set hysteresis to 0.  The reason I see no other workaround is that the longest response time that FanControl offers in the curve editor is 60 seconds, the smallest non-zero hysteresis that FanControl offers is 1C, and in principle a temperature source could take longer than 60 seconds for each 1C change.

 

I wrote yesterday that the purpose of hysteresis is stability.  I should have written: the purpose of hysteresis is stability when near the target.  Hopefully my explanation is wrong and FanControl would have sped up the fan if the temperature of E: had (gradually) risen above 39C.

Edited by Adrenalina
Added alternative explanation at end, that maybe FanControl would have sped up the fan if temperature had risen above 39C.
Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Adrenalina said:

Unfortunately, those small temperature changes can add up over time.  Could FanControl's non-response due to hysteresis allow computer parts to fry?

No.

 

In your case, you got 1 deg hysteresis, so this is why it "skips" certain points in your graph. Simply put a 0 deg hysteresis if you want every possible temperature step to be executed.

Link to comment
Share on other sites

Link to post
Share on other sites

14 minutes ago, Rem0o said:

No.

 

In your case, you got 1 deg hysteresis, so this is why it "skips" certain points in your graph. Simply put a 0 deg hysteresis if you want every possible temperature step to be executed.

That explanation makes sense.  Also, as far as I can tell, the SMART temperature attributes of drives are whole numbers, so I figure it would be impossible for FanControl to offer a non-zero hysteresis setting less than 1C, for example 0.5C, that would behave differently than hysteresis=1C would behave.

 

An alternative I wondered about is to offer an "infinity" response time option.  Given a {hysteresis=1C,response=infinity} pair, a gradual (longer than 60 seconds) 1C temperature change would cause FanControl to change the fan speed.  I figure this pair would behave the same as 0 hysteresis, given that the SMART temperature attribute is a whole number.  But perhaps it would behave better than 0 hysteresis for temperature sensors that return a temperature that's more precise than a whole number.

 

Am still wondering about the "slippery slope" question, which I think hasn't yet been addressed.  It's about another way that the fan speed might get stuck.  Here again is the scenario: Large hysteresis, small stepsize configured.  The temperature rises from T0 to T1 and a few seconds later rises from T1 to T2.  T1-T0 exceeds the hysteresis, but T2-T1 is less than the hysteresis.  Due to the small stepsize, the fan speed hasn't yet reached the T1 speed when the temperature increases to T2.  Will the fan speed settle at the T1 speed or continue stepping up to the T2 speed? (In this scenario, I think it would be irrational to want the speed to settle at the T1 speed.)

Link to comment
Share on other sites

Link to post
Share on other sites

50 minutes ago, Adrenalina said:

Am still wondering about the "slippery slope" question, which I think hasn't yet been addressed.  It's about another way that the fan speed might get stuck.  Here again is the scenario: Large hysteresis, small stepsize configured.  The temperature rises from T0 to T1 and a few seconds later rises from T1 to T2.  T1-T0 exceeds the hysteresis, but T2-T1 is less than the hysteresis.  Due to the small stepsize, the fan speed hasn't yet reached the T1 speed when the temperature increases to T2.  Will the fan speed settle at the T1 speed or continue stepping up to the T2 speed? (In this scenario, I think it would be irrational to want the speed to settle at the T1 speed.)

It will set at T1 speed, since T1 triggered the change, but then T2 never triggered it from T1. Step size has nothing to do with the hysteresis mechanism.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×