In a previous article I describe how I built a mobile Allstar node. I carry this node me with when I go to a meeting, or on a trip, leaving the node running in my car. California is a sunny state, and the inside of a car can get hot. As you can see in pictures in my previous post, I have installed a fan in the Allstar node case.
Fan Driver
The main problem with my setup was that the fan was running all the time. To conserve the battery and avoid unnecessary fan noise, I wanted to turn the fan on only when things got too hot inside the case. To achieve that I needed to check the temperature and use the GPIO to turn on the fan.
I experimented with the circuit schematic published at the end of this section. It was working fine, but I decided to buy an already made circuit that I found on Amazon.

The FET Trigger Switch Driver Module does the same thing my experiment did. Its price is very attractive. Designing and ordering my own PCB would end up being more expensive.
I connected the +12 Volt and the ground from the power supply to one side of the circuit. The fan is connected to the other side. I also soldered 2 leads that are plugged on the Raspberry Pi's GPIO. I used the pin 26 for that. This pin is easy to find. It is located at the end of the GPIO bus and there is a ground next to it.
Feel free to use a different pin but you will need to make sure it is
not used by something else. You will also need to edit the program and
change the constant FAN_PIN
in the program to the pin number you
choose to use.

Program
The Raspberry Pi CPU is reporting its internal temperature. I use this internal temperature sensor to control the fan. When my Allstar node runs in a moderately warm environment, the internal CPU temperature is below 40ÂșC. If the temperature inside the case increases or if the CPU starts working harder, the internal temperature of the CPU increases and the fan is started. This works well without having to use an external sensor.
The Following program gets the temperature and turns on the fan if the
threshold temperature has been reached. Feel free to change the
THRESHOLD
constant to your liking.
#!/usr/bin/python
#
# (c) W6BSD Fred Cirera
# https://github.com/0x9900/pifan
#
import atexit
import logging
import os
import time
import RPi.GPIO as io
TEMPFILE = "/sys/class/thermal/thermal_zone0/temp"
THRESHOLD = 42.0
FAN_PIN = 26
SLEEP = 31
io.setmode(io.BCM)
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',
datefmt='%H:%M:%S', level=logging.INFO)
class Fan(object):
"""Manages the fan. This class initialise the GPIO pin and provide the
methods to turn on and off the fan"""
def __init__(self, pin=FAN_PIN):
self._pin = pin
io.setup(self._pin, io.OUT, initial=io.LOW)
logging.info('GPIO pin(%s) configured', self._pin)
def on(self):
if io.input(self._pin) is io.HIGH:
return
io.output(self._pin, io.HIGH)
logging.debug('Fan(%d) -> ON', self._pin)
def off(self):
if io.input(self._pin) is io.LOW:
return
io.output(self._pin, io.LOW)
logging.debug('Fan(%d) -> OFF', self._pin)
def cleanup(self):
logging.info('cleanup')
io.cleanup()
def get_temp():
try:
with open(TEMPFILE, "r") as tempfd:
rawtemp = tempfd.readline().strip()
except IOError as err:
logging.error(err)
return 0
temp = float(rawtemp) / 1000
logging.debug("Temperature: %.2f", temp)
return temp
def set_loglevel():
log_level = os.getenv('LOGLEVEL')
if not log_level:
return
logger = logging.getLogger()
try:
level = logging._checkLevel(log_level.upper())
except ValueError as err:
logging.error(err)
else:
logger.setLevel(level)
def main():
set_loglevel()
fan = Fan(FAN_PIN)
atexit.register(fan.cleanup)
while True:
if get_temp() > THRESHOLD:
fan.on()
else:
fan.off()
time.sleep(SLEEP)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
logging.critical('Interrupted by user')
You can find the most recent version of this program on my
https://github.com/0x9900/pifan account. This version also
contains an installation script as well as a systemd
service file.
Using this script will install fan.service
and the program managing
the fan will automatically start as soon as the RPi starts.
The README file will give you all the instructions to run the installation script as well as the dependencies.
Note
I am now using the same system on my APRS iGAte