5

The fan speed control when running Ubuntu 23.10 on a Raspberry Pi 5 does not appear to be working. The fan runs at near maximum speed all the time and the cur_state in /sys/class/thermal/cooling_device0/ is stuck at the value of 4 no matter what the CPU temperature. I suspect it is related to this fault reported on Raspberry Pi OS: https://forums.raspberrypi.com/viewtopic.php?t=356881

Anyone else had any success with this?

4 Answers4

2

This has since been fixed as part of a kernel update.

You can update your Ubuntu Server installation with:

sudo apt update
sudo apt upgrade

After a reboot, the fan speed will behave as expected.

1

There is now a patch to a kernel build in ppa:waveform/fan-fix (https://launchpad.net/~waveform/+archive/ubuntu/fan-fix) which should serve as a temporary fix until the next kernel release. This allows the fan speed control to work ,but there is some concern that the hysteresis is being ignored, so this may not be the final fix.

  • I've been looking for this for a while now; I have 2 RP4 with POE+ hats and I had to hardcode the fans state to 3, but the noise was really annoying. I also posted the question in raspberrypi.stackexchange.com but it was down-voted and deleted, Thanks @Steve Pringle for the link to the kernel patch PPA, this definitely solved the issue! – Esteban Pereira Dec 05 '23 at 15:21
0

Its annoying, what I've been doing is just swapping the value until we get a new stable kernel:

sudo bash
cat > /sys/class/thermal/cooling_device0/cur_state
2
<CTRL-D>
Billy
  • 1
0

I was also annoyed by this and decided to let Python do all the work. Feel free to use this https://pastebin.com/SbFb4LYE .

from subprocess import run as srun, PIPE
from time import sleep
from datetime import timedelta as td, datetime as dt

Use step values to activate desired FAN value

STEP1 = 48 STEP2 = 60 STEP3 = 65 STEP4 = 72

SLEEP_TIMER = 1

TICKS = 3 DELTA_TEMP = 3 DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S' fanControlFile = '/sys/class/thermal/cooling_device0/cur_state'

def main(): print("Running FAN control for RPI5 Ubuntu") t0 = dt.now()

command = f'tee -a {fanControlFile} &gt; /dev/null'
oldSpeed = 0
ticks = 0

speed = 1
lastTemp = 0

while True:
    sleep(SLEEP_TIMER) # force 1 second timer, just to reduce polling calls
    t1 = dt.now()
    if(t1 + td(minutes=TICKS) &gt; t0):
        t0 = t1

        tempOut = getOutput('vcgencmd measure_temp')
        try:
            cels = int(tempOut.split('temp=')[1][:2])
        except:
            cels = 40

        if STEP1 &lt; cels &lt; STEP2:
            speed = 1
        elif STEP2 &lt; cels &lt; STEP3:
            speed = 2
        elif STEP3 &lt; cels &lt; STEP4:
            speed = 3
        elif cels &gt;= STEP4:
            speed = 4

        deltaTempNeg = lastTemp - DELTA_TEMP
        deltaTempPos = lastTemp + DELTA_TEMP

        if oldSpeed != speed and not(deltaTempNeg &lt;= cels &lt;= deltaTempPos):
            print(f'oldSpeed: {oldSpeed} | newSpeed: {speed}')
            print(f'{deltaTempNeg}ºC &lt;= {cels}ºC &lt;= {deltaTempPos}ºC')
            print(f'{&quot;#&quot;*30}\n' +
                f'Updating fan speed!\t{t0.strftime(DATETIME_FORMAT)}\n' +
                f'CPU TEMP: {cels}ºC\n' +
                f'FAN speed will be set to: {speed}\n' +
                f'{&quot;#&quot;*30}\n')

            _command = f'echo {speed} | sudo {command}'
            callShell(_command, debug=True)
            checkVal = getOutput(f'cat {fanControlFile}')
            print(f'Confirm FAN set to speed: {checkVal}')

            oldSpeed = speed
            lastTemp = cels
            ticks = 0

        # Log minor details
        ticks += 1
        if(ticks &gt; TICKS * 3):
            ticks = 0
            print(f'Current Temp is: {cels}ºC\t{t0.strftime(DATETIME_FORMAT)}')

def callShell(cmd, shell=True, debug=False): if debug: print(f'Calling: [{cmd}]') return srun(f'''{cmd}''', stdout=PIPE, shell=shell)

def getOutput(cmd, shell=True): stdout = callShell(cmd, shell=shell).stdout

try:
    stdout = stdout.decode('utf-8')
except:
    pass

return stdout

RUN SCRIPT

main()

karel
  • 114,770