Keeping your AllStar node cool

Posted by Fred C. (W6BSD) on Jul 28 2019

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.

Pi Fan controller
FET Switch Module

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.

Experimental schematic
Fan control experiment

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

Tags:  AllStar    RaspberryPi    Python


Comments !