1

Is there a way to run some kind of PWM for fan speed control inside bash script?

Here is my current script

#!/bin/bash
### BEGIN INIT INFO
# Provides:          rpipwm
# Required-Start:    $local_fs 
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: rpipwm
### END INIT INFO

    a="echo 20 > /sys/class/gpio/unexport;"
    a=$a"echo 20 > /sys/class/gpio/export;"
    a=$a"echo out > /sys/class/gpio/gpio20/direction"
    eval $a
#start loop script
while true;
do
    #Read temp
    cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp)
    cpuTemp1=$(($cpuTemp0/1000))
    temp=$cpuTemp1

    a=""

    #If temperature is equal or lower than 39, the fan will stop spinning
    if [[ $(bc <<< "$temp <= 39") == 1 ]] ;
    then
        a=$a"echo 0 > /sys/class/gpio/gpio20/value"
    fi
    #If temperature is between 40 and 42.99, the fan will start with 2 second burst and 1 second sleep
    if [[ $(bc <<< "$temp >= 40 && $temp <= 43") == 1 ]] ;
    then
        a=$a"echo 1 > /sys/class/gpio/gpio20/value; sleep 2; echo 0 > /sys/class/gpio/gpio20/value; sleep 1 "
    fi
    #If temperature is between 44 and 48.99, the fan will start with 5 second burst and 1 second sleep
    if [[ $(bc <<< "$temp > 44 && $temp <= 49") == 1 ]] ;
    then
        a=$a"echo 1 > /sys/class/gpio/gpio20/value; sleep 5; echo 0 > /sys/class/gpio/gpio20/value; sleep 1" 
    fi
    #If temperature is equal or higher than 50, the fan will start spinning constantly
    if [[ $(bc <<< "$temp >= 50") == 1 ]] ;
    then
        a=$a"echo 1 > /sys/class/gpio/gpio20/value" 
    fi

    eval $a

    sleep 0.1
done

I want to avoid sleep or somehow simulate PWM to my fan have real speed control instand of ON/OFF in defined intervals.

Can someone help me?

Thanks!

4
  • What PWM are you trying to generate? We need to know the frequency and the number of steps between on and off.
    – joan
    Jul 18, 2016 at 7:27
  • I need to experiment that yet. Currently script just on/off fan in certein time my fan what is not good for me. Jul 18, 2016 at 7:40
  • I don't see how to help without knowing the sort of PWM you need to control the fan.
    – joan
    Jul 18, 2016 at 7:57
  • Let's try something like this: 100Hz - 50% duty cycle. On this example I can build other things. Thanks! Jul 18, 2016 at 8:03

2 Answers 2

1

Personally I'd use one of the many libraries and/or daemons available to you to do the PWM.

Have a look at servoblaster and its clones which provide daemons to provide dedicated PWM.

Or perhaps have a look at the PWM features provided by wiringPi with the bundled gpio utility.

Another alternative is my pigpio daemon and the pigs utility which provides multiple ways of generating PWM.

All of these can be called by a bash script.

1

BASH script for PWM

function gpiopwm() {
    sleep_low=$(awk -v freq="$2" -v duty="$3"  'BEGIN{print (1/freq)*((100-duty)/100)}')
    sleep_high=$(awk -v freq="$2" -v duty="$3"  'BEGIN{print (1/freq)*((100-(100-duty))/100)}')
    var_count=0
    repeat=1000
    while [ $var_count -lt $repeat ]
    do
        echo 1 > /sys/class/gpio/gpio$1/value
        sleep $sleep_high
        echo 0 > /sys/class/gpio/gpio$1/value
        let var_count=var_count+1
        if [ $var_count -le $repeat ]
    then
        sleep $sleep_low
    fi
        done
}

Based on the frequency & duty cycle parameter, this function 'on' and 'off' the GPIO in different wavelength

Full script for PWM based on CPU temperature using BASH is @ https://github.com/mohdismailj/fancontrol

Refer my implementation

2
  • 2
    Could you please provide a full description of all of the code here. Also, please stop linking to the same YouTube video without disclosing your affiliation.
    – Darth Vader
    Feb 16, 2021 at 9:27
  • This is cool code Feb 16, 2021 at 12:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.