├── LICENSE ├── README.md ├── odroid-fan-controller └── odroid-xu4-fan-control.sh /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Tomasz Nazar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### This is for the latest 6.1.y XU4 kernel as of October 2023 2 | 3 | ### What does it do? 4 | 5 | Makes Odroid XU4 fan silent on idle load and quite on medium load 6 | 7 | ### Is it safe to use? 8 | 9 | When script quits it brings fan mode back to *automatic* "factory" settings. 10 | 11 | ## Usage 12 | ``` 13 | sudo apt-get install git 14 | git clone https://github.com/f1vefour/odroid-xu4-fan-control.git 15 | cd odroid-xu4-fan-control 16 | chmod +x odroid-xu4-fan-control.sh 17 | sudo ./odroid-xu4-fan-control.sh 18 | ``` 19 | ## Installation 20 | 21 | To make it start when system boots: 22 | 23 | edit odroid-fan-controller and add the path of the odroid-xu4-fan-control.sh script (full-pathname), then do the following to add it 24 | to the runlevels 25 | 26 | cd /etc/init.d/ 27 | #adjust to correct, absolute path below 28 | sudo ln -s ~/odroid-xu4-fan-control /etc/init.d/odroid-fan-controller 29 | sudo update-rc.d odroid-fan-controller defaults 30 | 31 | you can also use the following to start the controller 32 | 33 | sudo /etc/init.d/odroid-fan-controller start 34 | 35 | or 36 | 37 | sudo /etc/init.d/odroid-fan-controller stop 38 | 39 | to stop the controller 40 | -------------------------------------------------------------------------------- /odroid-fan-controller: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: odroid-fan-controller 4 | # Required-Start: $remote_fs $syslog 5 | # Required-Stop: $remote_fs $syslog 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Start daemon at boot time 9 | # Description: Enable service provided by daemon. 10 | ### END INIT INFO 11 | 12 | #adjust dir below. Example: dir="/home/nthx/odroid-xu4-fan-control/" 13 | dir="" 14 | user="root" 15 | cmd="./odroid-xu4-fan-control.sh" 16 | 17 | name=`basename $0` 18 | pid_file="/var/run/$name.pid" 19 | stdout_log="/var/log/$name.log" 20 | stderr_log="/var/log/$name.err" 21 | 22 | get_pid() { 23 | cat "$pid_file" 24 | } 25 | 26 | is_running() { 27 | [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1 28 | } 29 | 30 | case "$1" in 31 | start) 32 | if is_running; then 33 | echo "Already started" 34 | else 35 | echo "Starting $name" 36 | cd "$dir" 37 | sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" & 38 | echo $! > "$pid_file" 39 | if ! is_running; then 40 | echo "Unable to start, see $stdout_log and $stderr_log" 41 | exit 1 42 | fi 43 | fi 44 | ;; 45 | stop) 46 | if is_running; then 47 | echo -n "Stopping $name.." 48 | kill `get_pid` 49 | for i in {1..10} 50 | do 51 | if ! is_running; then 52 | break 53 | fi 54 | 55 | echo -n "." 56 | sleep 1 57 | done 58 | echo 59 | 60 | if is_running; then 61 | echo "Not stopped; may still be shutting down or shutdown may have failed" 62 | exit 1 63 | else 64 | echo "Stopped" 65 | if [ -f "$pid_file" ]; then 66 | rm "$pid_file" 67 | fi 68 | fi 69 | else 70 | echo "Not running" 71 | fi 72 | ;; 73 | restart) 74 | $0 stop 75 | if is_running; then 76 | echo "Unable to stop, will not attempt to start" 77 | exit 1 78 | fi 79 | $0 start 80 | ;; 81 | status) 82 | if is_running; then 83 | echo "Running" 84 | else 85 | echo "Stopped" 86 | exit 1 87 | fi 88 | ;; 89 | *) 90 | echo "Usage: $0 {start|stop|restart|status}" 91 | exit 1 92 | ;; 93 | esac 94 | 95 | exit 0 96 | -------------------------------------------------------------------------------- /odroid-xu4-fan-control.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Loud fan control script to lower speed of fan based on current 4 | # max temperature of any cpu 5 | # 6 | # See README.md for details. 7 | 8 | #set to false to suppress logs 9 | DEBUG=false 10 | 11 | # Make sure only root can run our script 12 | if (( $EUID != 0 )); then 13 | echo "This script must be run as root:" 1>&2 14 | echo "sudo $0" 1>&2 15 | exit 1 16 | fi 17 | 18 | 19 | TEMPERATURE_FILE="/sys/devices/virtual/thermal/thermal_zone0/temp" 20 | FAN_MODE_FILE="/sys/devices/platform/pwm-fan/automatic" 21 | FAN_SPEED_FILE="/sys/devices/platform/pwm-fan/pwm1" 22 | TEST_EVERY=3 #seconds 23 | new_fan_speed_default=80 24 | LOGGER_NAME=odroid-xu4-fan-control 25 | 26 | #make sure after quiting script fan goes to auto control 27 | function cleanup { 28 | ${DEBUG} && logger -t $LOGGER_NAME "event: quit; temp: auto" 29 | echo 1 > ${FAN_MODE_FILE} 30 | } 31 | trap cleanup EXIT 32 | 33 | function exit_xu4_only_supported { 34 | ${DEBUG} && logger -t $LOGGER_NAME "event: non-xu4 $1" 35 | exit 2 36 | } 37 | if [ ! -f $TEMPERATURE_FILE ]; then 38 | exit_xu4_only_supported "a" 39 | elif [ ! -f $FAN_MODE_FILE ]; then 40 | exit_xu4_only_supported "b" 41 | elif [ ! -f $FAN_SPEED_FILE ]; then 42 | exit_xu4_only_supported "c" 43 | fi 44 | 45 | 46 | current_max_temp=`cat ${TEMPERATURE_FILE} | cut -d: -f2 | sort -nr | head -1` 47 | echo "fan control started. Current max temp: ${current_max_temp}" 48 | echo "For more logs see:" 49 | echo "sudo tail -f /var/log/syslog" 50 | 51 | while [ true ]; 52 | do 53 | echo 0 > ${FAN_MODE_FILE} #to be sure we can manage fan 54 | 55 | current_max_temp=`cat ${TEMPERATURE_FILE} | cut -d: -f2 | sort -nr | head -1` 56 | ${DEBUG} && logger -t $LOGGER_NAME "event: read_max; temp: ${current_max_temp}" 57 | 58 | new_fan_speed=0 59 | if (( ${current_max_temp} >= 75000 )); then 60 | new_fan_speed=255 61 | elif (( ${current_max_temp} >= 70000 )); then 62 | new_fan_speed=200 63 | elif (( ${current_max_temp} >= 68000 )); then 64 | new_fan_speed=130 65 | elif (( ${current_max_temp} >= 66000 )); then 66 | new_fan_speed=80 67 | elif (( ${current_max_temp} >= 63000 )); then 68 | new_fan_speed=80 69 | elif (( ${current_max_temp} >= 60000 )); then 70 | new_fan_speed=0 71 | elif (( ${current_max_temp} >= 58000 )); then 72 | new_fan_speed=0 73 | elif (( ${current_max_temp} >= 55000 )); then 74 | new_fan_speed=0 75 | else 76 | new_fan_speed=0 77 | fi 78 | ${DEBUG} && logger -t $LOGGER_NAME "event: adjust; speed: ${new_fan_speed}" 79 | echo ${new_fan_speed} > ${FAN_SPEED_FILE} 80 | 81 | sleep ${TEST_EVERY} 82 | done 83 | --------------------------------------------------------------------------------