Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner Author

Enchufa2 commented Jun 15, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.