Hardware: Raspberry Pi - 512MB (Heatsink on the CPU)
Software: Raspian
Power: 5V 1.2A
Overclocked to 1GHz
Fan: simple 2wire Fan 40mm x 40mm (http://www.neuhold-elektronik.at/catsho ... ts_id=2895)
CPU with heatsink:
I bougth a case from modmypi.com https://www.modmypi.com/raspberry-pi-ca ... case-black,
but i dont wanted to destroy the case, so i made a new case to mount the fan.
Here are the results:


I used the "base" from the bought case and made a new "top". It's made of polystyrene, i love the stuff

The fan is powered via the GPIOs (no problems with power recognized) but because its a simple 2-wire fan I had to use a trasitor to drive the fan via PWM.
Here is a very simple circuit diagram:

So, that was the hardware-part, let's start with the software.
As you can see at the fan's-seller-page, the fan can be quite loud (30,5 dBA), so PWM is a usefull tool to reduce the RPM and the noise.
Also the process should start at boot up.
(Node: First I've tried python but, whyever, the script can't load the wiringPi librarys at startup...
I also tried software-pwm, but it's to slow for the fan and makes realy strange noises.)
So here is my little C-Programm for a Hardware-PWM driven Fan:
Code: Select all
/*
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 &
*/
It's a simple, linear PWM-Control. The hotter the CPU, the faster the Fan.
Simple and Easy ;D
Comments, criticism, improvement suggestions,.. would be great

Last but not least:
Sry for my bad english
greets form Austria
