Monday, February 11, 2019

Control a cooling fan with gpio-fan (Device Tree Overlays)

I want to setup a cooling fan and enable it at temperature greater then 55 °C.
I found gpio-fan on device tree overlays.

Name:   gpio-fan
Info:   Configure a GPIO pin to control a cooling fan.
Load:   dtoverlay=gpio-fan,<param>=<val>
Params: gpiopin                 GPIO used to control the fan (default 12)
        temp                    Temperature at which the fan switches on, in
                                millicelcius (default 55000)
Reference: https://github.com/raspberrypi/firmware/tree/master/boot/overlays

Step to Setup

1. Setup a cooling fan and NPN transistor (S8050).

Reference:



2. Add config device tree overlays on /boot/config.txt.

dtoverlay=gpio-fan,gpiopin=12,temp=55000
 temp = 55000 is millicelcius

3. Restart Raspberry PI

After reboot success.

Hope you enjoy with it.



If you don't want to use gpio-fan overlay.

Create file on /home/pi/bin/temp_montior

#!/bin/bash

GPIO_PIN=12

HIGH_TEMP=50000
SAVE_TEMP=45000

function get_temp() {
  cat /sys/class/thermal/thermal_zone0/temp
}

function gpio_enable() {
  echo $1 > /sys/class/gpio/export
}

function gpio_disable() {
  echo $1 > /sys/class/gpio/unexport
}

function gpio_set_output() {
  echo out > /sys/class/gpio/gpio$1/direction
}

function gpio_set_input() {
  echo in > /sys/class/gpio/gpio$1/direction
}

function gpio_set_on() {
  echo 1  > /sys/class/gpio/gpio$1/value
}

function gpio_set_off() {
  echo 0 > /sys/class/gpio/gpio$1/value
}

function cleanup() {
  QUIT=1
}

QUIT=0

#echo "Enable GPIO ${GPIO_PIN}"
gpio_enable $GPIO_PIN

#echo "Set GPIO ${GPIO_PIN} Output"
gpio_set_output $GPIO_PIN

#echo "set GPIO ${GPIO_PIN} on"
#gpio_set_on $GPIO_PIN

LASTSTATUS=0


trap cleanup SIGINT SIGTERM

while [ 1 ]; do
  cputemp=$(get_temp)
  #echo "CPU TEMP = $cputemp"
  if [ $LASTSTATUS = 0 ]; then
    if [ $cputemp -gt $HIGH_TEMP ]; then
      echo "FAN ON"
      echo "CPU TEMP = $cputemp"
      gpio_set_on $GPIO_PIN
      LASTSTATUS=1
    fi
  else
    if [ $cputemp -lt $SAVE_TEMP ]; then
      echo "FAN OFF"
      echo "CPU TEMP = $cputemp"
      gpio_set_off $GPIO_PIN
      LASTSTATUS=0
    fi
  fi
  if [ "$QUIT" = "1" ]; then break; fi
  sleep 1
done

#echo "set GPIO ${GPIO_PIN} off"
gpio_set_off $GPIO_PIN

#echo "Disable GPIO ${GPIO_PIN}"
gpio_disable $GPIO_PIN


Change mode for execute file

$ chmod 755 /home/pi/bin/temp_montior

Add this script to startup.
Edit /etc/rc.local and add line before exit 0

$ sudo nano /etc/rc.local

...
/home/pi/bin/temp_monitor &
...
exit0

You can change GPIO_PIN, HIGH_TEMP and SAVE_TEMP for gpio pin, start and stop fan





6 comments:

  1. and when the temperature goes low how do we do for turn off the fan?

    ReplyDelete
    Replies
    1. On source code of gpio-fan-overlay.dts

      https://github.com/raspberrypi/linux/blob/0d3c5fea8c6b309e1e61aae2389a4baf327d2967/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts


      This line (on default start at 55°C and stop at 45°C)


      cpu_hot: trip-point@0 {
      temperature = <55000>; /* (millicelsius) Fan started at 55°C */
      hysteresis = <10000>; /* (millicelsius) Fan stopped at 45°C */
      type = "active";
      };

      Delete
  2. Hi Chanchai! Very good this post, simple and functional!

    ReplyDelete
  3. Please compare your own info on how the command looks and compare that with what you wrote in code. Your dtoverlay code does not work! More precisely, it works by accident if one uses GPIO12 since it is a default. Instead of gpio_pin must be gpiopin!

    Plus, good electronic practice says there should be a resistor on data line, 560 ohm is a good one, letting through up to 500 mA.

    I like you provided all versions of how it can be done. I have no clue which OS you use as you did not write that.

    ReplyDelete
  4. Just want to add, for the official rpi 4 case fan you have to write 'gpiopin' instead of 'gpio_pin', like this:
    dtoverlay=gpio-fan,gpiopin=14,temp=55000

    ReplyDelete
  5. I recommend adding a flyback diode connected across the fan pos and gnd lines to prevent damage with fan switches off.
    I also recommend a few hundred ohms resistor between gpio pin and the base of the transistor to limit current draw.

    ReplyDelete