From 88a5d2a45ec3f7ebbe2e0e2a2a923283d78247a9 Mon Sep 17 00:00:00 2001 From: Ksan Date: Sat, 12 Apr 2025 22:55:14 +0200 Subject: [PATCH] Added basic functionality to control fans of nvidia gpu --- .gitignore | 1 + README.md | 22 +++++++++++++++++ main.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 main.cpp diff --git a/.gitignore b/.gitignore index 259148f..27fbe49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/fanControl # Prerequisites *.d diff --git a/README.md b/README.md index 441df3d..d188ccf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,24 @@ # fanControl Simple script for controlling your system fans + +Currently only works for nvidia gpu. + +To install just clone the repo and compile the code: + g++ -O3 -o fanControl main.cpp + +Best used with tmux and running sudo ./fanControl +
+

Setting custom fan curve

+To make your own custom fan curve just edit "TEMP_THRESHOLD" and "FAN_SPEED". +Example: TEMP_THRESHOLD[] = {30, 50, 80}; + FAN_SPEEd[] = {0, 30, 50, 80}; + + +When the GPU temperature is below 30°C, the fans will not spin (0% speed). + +Once the temperature reaches 30°C or higher, the fans will spin at 30% speed. + +When the temperature reaches 50°C or higher, the fan speed increases to 50%. + +At 80°C or higher, the fans will spin at full speed (80%). + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..151033b --- /dev/null +++ b/main.cpp @@ -0,0 +1,69 @@ +#include +#include +#include + +const int MIN_TEMP = 30; +const int MAX_TEMP = 80; +const int TEMP_THRESHOLD[] ={30, 40, 55, 60, 70, 80, 85}; +const int FAN_SPEED[] = { 0, 30, 40, 50, 60, 65, 80, 100}; + +int getTemperature(){ + std::string command = "nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits"; + + FILE* fp = popen(command.c_str(), "r"); + if(fp == NULL){ + std::cerr << "Failed to run command to get GPU temperature." << std::endl; + return -1; + } + char buffer[128]; + std::string result = ""; + while(fgets(buffer, sizeof(buffer), fp) != NULL){ + result += buffer; + } + + pclose(fp); + + int temp; + std::stringstream(result) >> temp; + + return temp; + +} + +void setGpuFanSpeed(int speed){ + if(speed < 0 || speed > 100){ + std::cerr << "Invalid fan speed:" << speed << ", speed must be between 0 and 100." << std::endl; + return; + } + + std::string command = "nvidia-settings --assign 'GPUTargetFanSpeed=" + std::to_string(speed) + "'"; + + if(system(command.c_str()) == 0){ + std::cout << "Fan speed set to " << speed << "%" << std::endl; + }else{ + std::cerr << "Failed to change fan speed." << std::endl; + } +} +int getFanSpeedFromTemperature(int temperature){ + for(size_t i = 0; i < std::size(TEMP_THRESHOLD); i++){ + if(temperature < TEMP_THRESHOLD[i]) return FAN_SPEED[i]; + + } + return FAN_SPEED[std::size(FAN_SPEED) - 1]; // max speed + +} +int main(int argc, char *argv[]){ + + while(true){ + int temperature = getTemperature(); + + if(temperature == -1){ + return 1; + } + + std::cout << "GPU temperature: " << temperature << "°C" << std::endl; + setGpuFanSpeed(getFanSpeedFromTemperature(temperature)); + sleep(5); + + } +}