Last active
March 2, 2018 09:45
-
-
Save Enchufa2/4bde3bab84eebedcc88e to your computer and use it in GitHub Desktop.
Fancontrol via Hardware PWM for RaspberryPi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Fancontrol via Hardware PWM for Raspian | |
Author: 2h4u | |
Date: 19.01.2013 | |
Version 2: | |
Now with dynamic PWM regulation! | |
*/ | |
#include <stdio.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include <stdlib.h> | |
#include <wiringPi.h> | |
//-------INIT-------// | |
int FAN = 1; | |
//------------------// | |
int PWM_ZERO = 550; | |
int PWM_MAX = 1024; | |
//------------------// | |
int TEMP_ZERO = 45000; | |
int TEMP_PWM = 50000; | |
int TEMP_MAX = 70000; | |
//---- getTemp -----// | |
FILE* tempfile; | |
int tempCache = 0; | |
//------ main ------// | |
int sleepTime = 5; | |
//------------------// | |
int getTemp () | |
{ | |
// Read Temp | |
tempfile = fopen ("/sys/class/thermal/thermal_zone0/temp", "r"); | |
fscanf (tempfile, "%d", &tempCache); | |
fclose (tempfile); | |
return tempCache; | |
} | |
int checkIfItsFirstRun () | |
{ | |
struct stat st; | |
int status = 0; | |
// Check if there is a configfile | |
if(stat ("/usr/share/fancontrol/config.txt",&st) == 0) | |
return 0; | |
else | |
{ | |
// if there is no configfile, check if there is the directory | |
if(stat ("/usr/share/fancontrol",&st) == 0) | |
{ | |
// create config.txt | |
FILE *outfile = fopen ("/usr/share/fancontrol/config.txt", "a+"); | |
if(!outfile) { | |
printf ("There was a problem opening /usr/share/fancontrol/config.txt for writing\n"); | |
fclose (outfile); | |
return 1; | |
} | |
else | |
{ // write standard config to config.txt | |
fprintf (outfile,"%s","#FAN-PIN\n1\n#Min. PWM-POWER (0-1024):\n550\n#Max. PWM-POWER (0-1024):\n1024\n#Fan stops at Temp (°C *1000):\n45000\n#Fan starts at Temp:\n50000\n#Fullspeed Fan at Temp:\n70000\n#Refresh Time (seconds):\n5\n") ; | |
} | |
fclose (outfile); | |
return 0; | |
} | |
else | |
{ | |
// create fancontrol-dir + config.txt | |
status = mkdir ("/usr/share/fancontrol", S_IRWXO) ; | |
if(status != 0) | |
{ | |
fprintf (stderr, "Unable to create /usr/share/fancontrol %s\n", strerror (errno)) ; | |
return status; | |
} | |
// now create the config.txt | |
FILE *outfile = fopen ("/usr/share/fancontrol/config.txt", "a+"); | |
if(!outfile) { | |
printf ("There was a problem opening /usr/share/fancontrol/config.txt for writing\n"); | |
fclose (outfile); | |
return 1; | |
} | |
else | |
{ // write standard config to config.txt | |
fprintf (outfile,"%s","#FAN-PIN\n1\n#Min. PWM-POWER (0-1024):\n550\n#Max. PWM-POWER (0-1024):\n1024\n#Fan stops at Temp (°C *1000):\n45000\n#Fan starts at Temp:\n50000\n#Fullspeed Fan at Temp:\n70000\n#Refresh Time (seconds):\n5\n") ; | |
} | |
fclose (outfile); | |
return 0; | |
} | |
} | |
} | |
int getConfig(void) | |
{ | |
char line[256]; | |
int wert = 0, linenum = 0 ; | |
FILE* configfile = fopen ("/usr/share/fancontrol/config.txt", "r"); | |
while(fgets (line, 256, configfile) != NULL) | |
{ | |
linenum++; | |
if(line[0] == '#') | |
continue; | |
// now read the configfile | |
if(sscanf (line, "%d", &wert) != 1) | |
{ | |
fprintf (stderr, "Syntax error, line %d\n", linenum); | |
continue; | |
} | |
// now allocate values | |
switch( linenum ) | |
{ | |
case 2: | |
FAN = wert; | |
break; | |
case 4 : | |
PWM_ZERO = wert; | |
break; | |
case 6 : | |
PWM_MAX = wert; | |
break; | |
case 8 : | |
TEMP_ZERO = wert; | |
break; | |
case 10 : | |
TEMP_PWM = wert; | |
break; | |
case 12 : | |
TEMP_MAX = wert; | |
break; | |
case 14 : | |
sleepTime = wert; | |
break; | |
} | |
} | |
fclose (configfile); | |
return 0; | |
} | |
int main () | |
{ | |
// check if wiringPi loaded correctly | |
if (wiringPiSetup () == -1) | |
{ | |
fprintf (stderr, "Unable to setup GPIO: %s\n", strerror (errno)) ; | |
return 1 ; | |
} | |
checkIfItsFirstRun (); | |
getConfig (); | |
pinMode (FAN, PWM_OUTPUT) ; | |
int temp = 0, pwmPercentage = 0, fanStatus = 0; | |
float tempOnePercent = 0, pwmOnePercent = 0, tempPercentage = 0, pwmPercentageDump = 0, tempDump = 0; | |
// Precalculations | |
tempOnePercent = ((TEMP_MAX - (float)TEMP_ZERO) / 100000) ; | |
pwmOnePercent = ((PWM_MAX - (float)PWM_ZERO) / 100) ; | |
printf( "FAN: %i \n", FAN); | |
printf( "tempOnePercent: %f \n", tempOnePercent); | |
printf( "pwmOnePercent: %f \n", pwmOnePercent); | |
while(1) | |
{ | |
temp = getTemp (); | |
printf( "temp: %i \n", temp); | |
if(temp > TEMP_PWM) | |
{ | |
while(temp > TEMP_ZERO) | |
{ // Calculate the PWM-Power | |
tempDump = ((temp - (float)TEMP_ZERO) / 1000) ; | |
tempPercentage = tempDump / tempOnePercent ; | |
pwmPercentageDump = tempPercentage * pwmOnePercent; | |
pwmPercentage = (int)( (pwmPercentageDump + PWM_ZERO)) ; | |
if(fanStatus == 0) | |
{ // Help the Fan to start | |
pwmWrite (FAN, PWM_MAX) ; | |
fanStatus = 1; | |
sleep (1) ; | |
} | |
pwmWrite (FAN, pwmPercentage) ; | |
sleep (sleepTime) ; | |
temp = getTemp (); | |
printf( "\ntemp: %i \n", temp); | |
printf( "pwmPercentage: %i \n", pwmPercentage); | |
printf( "tempDump: %f \n", tempDump); | |
printf( "tempPercentage: %f \n", tempPercentage); | |
printf( "pwmPercentageDump: %f \n", pwmPercentageDump); | |
} | |
} | |
else | |
{ | |
pwmWrite (FAN, 0) ; | |
fanStatus = 0; | |
sleep (sleepTime) ; | |
} | |
} | |
return 0 ; | |
} | |
/* | |
To Compile: | |
gcc -Wall -o fancontrol-hv2 Fancontrol-hv2.c -lwiringPi -lpthread | |
To Run automaticly at startup write the follwing before "exit 0" in /etc/rc.local: | |
/location/of/fancontrol-hv2 & | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Fancontrol via Hardware PWM for RaspberryPi | |
# Authors: Fernando Fernández, Iñaki Ucar | |
# Date: 18.08.2014 | |
# Path | |
GPIO=/usr/local/bin/gpio | |
# Limits | |
MIN_TEMP=40 | |
MAX_TEMP=69 | |
MIN_FAN=0 | |
MAX_FAN=1024 | |
# Run forever | |
while [ 1 ]; do | |
# What's the CPU temp? | |
temp=$(cat /sys/class/thermal/thermal_zone0/temp) | |
temp=$((temp/1000)) | |
# Variable temperature control | |
if [ $temp -gt $MIN_TEMP ] && [ $temp -lt $MAX_TEMP ]; then | |
fan=$(((temp - MIN_TEMP) * MAX_FAN / (MAX_TEMP - MIN_TEMP))) | |
secs=1 | |
# Maximum fan RPM | |
elif [ $temp -ge $MAX_TEMP ]; then | |
fan=$MAX_FAN | |
secs=1 | |
# Switch off the fan | |
else | |
fan=$MIN_FAN | |
secs=60 | |
fi | |
$GPIO -g mode 18 pwm | |
$GPIO -g pwm 18 $fan | |
# Show current state and pause for a while | |
echo "temp: $temp'C | fan: $((fan * 100 / MAX_FAN))% | pause: $secs""s" | |
sleep $secs | |
done | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Source: