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.py
and 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()