Skip to content

Instantly share code, notes, and snippets.

@Enchufa2
Last active March 2, 2018 09:45
Show Gist options
  • Save Enchufa2/4bde3bab84eebedcc88e to your computer and use it in GitHub Desktop.
Save Enchufa2/4bde3bab84eebedcc88e to your computer and use it in GitHub Desktop.
Fancontrol via Hardware PWM for RaspberryPi
/*
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 &
*/
#!/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
@Enchufa2
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment