ChilledPi2 - Advanced fan control for keeping your Raspberry Pi cool
ChilledPi was a useful script, but what if you want to drive each fan differently, maybe even from different temperature readings?

Well now you can make your PicoBorg based cooling system even better with ChilledPi2!
ChilledPi2 can read multiple sensors and control each of the 4 fan drives separately as you desire:

The configuration is a little more complex than before:
Here's the code, you can download the ChilledPi2 script file as text here
Save the text file on your pi as ChilledPi2.py
Make the script executable using
and run using

Well now you can make your PicoBorg based cooling system even better with ChilledPi2!
ChilledPi2 can read multiple sensors and control each of the 4 fan drives separately as you desire:

The configuration is a little more complex than before:
- lSensors, lines 38-40
This is a list of the sensors you wish to read (they will all be displayed to the user, you can therefore read more then you control from), formatted as follows:
[name, terminal command to read the sensor, multiplier],
this allows you to query any sensor you can read from the command line - lFans, lines 44-49
This is a list of which drives to control, stating which sensor they are based on, the temperature to turn on, and the temperature to turn off, formatted as follows:
[DRIVE_1, 'Processor', 31.0, 33.0],
this allows you to setup each fan individually, as well as control how many fans re in use (no reference to a drive pin will mean it is ignored by the script). - interval, line 52
The number of seconds between readings, smaller responds quicker but uses more processing power
Here's the code, you can download the ChilledPi2 script file as text here
Save the text file on your pi as ChilledPi2.py
Make the script executable using
chmod +x ChilledP2i.pyand run using
sudo ./ChilledPi2.py
#!/usr/bin/env python
# coding: latin-1
# Import library functions we need
import time
import sys
import os
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Set which GPIO pins the drive outputs are connected to
DRIVE_1 = 4
DRIVE_2 = 18
DRIVE_3 = 8
DRIVE_4 = 7
# Set all of the drive pins as output pins
GPIO.setup(DRIVE_1, GPIO.OUT)
GPIO.setup(DRIVE_2, GPIO.OUT)
GPIO.setup(DRIVE_3, GPIO.OUT)
GPIO.setup(DRIVE_4, GPIO.OUT)
# Map the on/off state to nicer names for display
dName = {}
dName[True] = 'ON '
dName[False] = 'OFF'
# Function to set all drives off
def MotorOff():
GPIO.output(DRIVE_1, GPIO.LOW)
GPIO.output(DRIVE_2, GPIO.LOW)
GPIO.output(DRIVE_3, GPIO.LOW)
GPIO.output(DRIVE_4, GPIO.LOW)
# Setup for sensors
# [name, terminal command to read the sensor, multiplier],
lSensors = [
['Processor', 'cat /sys/class/thermal/thermal_zone0/temp', 0.001],
]
# Setup for individual fans, units for high / low are post multiplier
# [drive, sensor name, low level 'off', high level 'on'],
lFans = [
[DRIVE_1, 'Processor', 31.0, 33.0],
[DRIVE_2, 'Processor', 33.0, 35.0],
[DRIVE_3, 'Processor', 35.0, 37.0],
[DRIVE_4, 'Processor', 37.0, 39.0],
]
# Setup for processor monitor
interval = 1 # Time between readings in seconds
try:
# Start by turning all drives off
MotorOff()
raw_input('You can now turn on the power, press ENTER to continue')
# Add an extra field to each sensor for the latest reading
for sensor in lSensors:
sensor.append(0.0)
# Change the fan configuration to use an index number, rather than a name
for fan in lFans:
found = False
for i in range(len(lSensors)):
if lSensors[i][0] == fan[1]:
fan[1] = i
found = True
break
if not found:
print 'No sensor named "%s" listed!'
sys.exit()
while True:
# Read the temperatures in from the various files
for sensor in lSensors:
fSensor = os.popen(sensor[1])
sensor[3] = float(fSensor.read()) * sensor[2]
fSensor.close()
# Display the fan reading
print '%s: %02.3f' % (sensor[0], sensor[3]),
print ''
# Go through each configured fan in turn
for fan in lFans:
sensor = lSensors[fan[1]]
# Adjust the fan depending on current status
if GPIO.input(fan[0]):
if sensor[3] <= fan[2]:
# We have cooled down enough, turn the fan off
GPIO.output(fan[0], GPIO.LOW)
else:
if sensor[3] >= fan[3]:
# We have warmed up enough, turn the fan on
GPIO.output(fan[0], GPIO.HIGH)
# Print the current state of all 4 drives
print '%s %s %s %s' % (dName[GPIO.input(DRIVE_1)], dName[GPIO.input(DRIVE_2)], dName[GPIO.input(DRIVE_3)], dName[GPIO.input(DRIVE_4)])
# Wait a while
time.sleep(interval)
except KeyboardInterrupt:
# CTRL+C exit, turn off the drives and release the GPIO pins
print 'Terminated'
MotorOff()
raw_input('Turn the power off now, press ENTER to continue')
GPIO.cleanup()

