Jump to content

PWM Fan on Nanopi M4 ??


perlian

Recommended Posts

Hi Team,

 

I tried to use the script on my nanopi m4v1 with sata head on armbian buster server kernel 5.4.

 

After starting the script (via systemctl manually or during system boot) the fan starts for apprx. 5 sec and the stops (and will not start again)

 

systemctl status pwm.fan gives:

 

Quote


● pwm-fan.service - pwm-fan
   Loaded: loaded (/etc/systemd/system/pwm-fan.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2020-06-23 14:51:36 CEST; 10min ago
 Main PID: 4295 (start-rk3399-pw)
    Tasks: 2 (limit: 2211)
   Memory: 1.9M
   CGroup: /system.slice/pwm-fan.service
           ├─4295 /bin/bash /usr/bin/start-rk3399-pwm-fan.sh
           └─7845 sleep 2s

Jun 23 14:51:36 openmediavault systemd[1]: Started pwm-fan.
Jun 23 15:01:54 openmediavault systemd[1]: /etc/systemd/system/pwm-fan.service:10: Unknown section 'nstall'. Ignoring.
Jun 23 15:01:54 openmediavault systemd[1]: /etc/systemd/system/pwm-fan.service:10: Unknown section 'nstall'. Ignoring.
Jun 23 15:01:59 openmediavault systemd[1]: /etc/systemd/system/pwm-fan.service:10: Unknown section 'nstall'. Ignoring.
Jun 23 15:02:00 openmediavault systemd[1]: /etc/systemd/system/pwm-fan.service:10: Unknown section 'nstall'. Ignoring.
 

 

has anybody a working solution? do not want to have a running fan all the time ;)

 

best regards

 

alex

Link to comment
Share on other sites

2 hours ago, onkelalex1234 said:

I tried to use the script on my nanopi m4v1 with sata head on armbian buster server kernel 5.4.


Most likely not developed / ported to a modern kernel. In case you need this function, you need to remain on old stock kernel. Or contribute to the development.

Link to comment
Share on other sites

Hello

Just using Carlos Gomes git (https://cgomesu.com/blog/Nanopi-m4-mini-nas/) I have the fan working with pwm on the latest

version of armbian, with kernel 5.8:

$ uname -a

$ Linux nanoNas 5.8.11-rockchip64 #20.08.4 SMP PREEMPT Wed Sep 23 17:51:13 CEST 2020 aarch64 GNU/Linux

 

I slightly modify the script to add some hysteresis when the fan slow down, in order to avoid continuous stop and go when the nas is idle.

...

while true
do
    temp0=$(cat /sys/class/thermal/thermal_zone1/temp)
    duty0=$(cat /sys/class/pwm/pwmchip1/pwm0/duty_cycle)
    # If you changed the length of $CpuTemps and $DutyCycles, then change the following length, too
    for i in 0 1 2 3 4 5; do
        # add some hysteresis when the fan speeds down to avoid continuous stop and go
        if [ $duty0 -eq ${DutyCycles[$i]} ]; then
            j=2
        else
            j=0
        fi
        if [ $temp0 -gt ${CpuTemps[$i]}-$j ]; then
            DUTY=${DutyCycles[$i]}

...

I use a simple 12cm, 2 pins fan to cool down the 4 disks, 3.5", 4TB each. Supply is provided by a 12 V, 6 A module.

The sata hat is missing a function (available on my previous Netgear ReadyNas) to start the disks in sequence, so

I added a timer to let the nanopi start, then 2 disks, then the 2 last ones. Otherwise, when switching on, the nanoPi

detects a brownout on the 5 V line and stop everything.

Edited by Werner
Add code for better readability
Link to comment
Share on other sites

My post was edited while I was modifying it (thanks Werner for the readability), but then I couldn't save  :-(

So some adds-on here.

 

I change the set points to adapt to my fan:

...
# declare -a CpuTemps=(75000 65000 55000 40000 25000 0)
declare -a CpuTemps=(75000 68000 60000 50000 40000 0)
# Duty cycle for each CPU temp range
# declare -a DutyCycles=(40000 6000 3000 2000 1500 0)
declare -a DutyCycles=(40000 30000 20000 12000 8000 0)
...

After modifying the script, don't forget to restart  the service:

# systemctl restart pwm-fan.service


When starting, the fan will run for 10 s, which shows the service is working. Then it will stop and restart only if the temperature is above the lower temperature threshold and the corresponding duty cycle high enough to allow the fan to start. This may need some trials to find the correct values, as each fan reacts differently.


I exchanged the radiator provided with the sataHat by a bigger one, as the original was getting very hot  (cannot keep a finger on it), even when the system was idle. Now temperatures of both the radiators of nanoPi and sataHat are similar (finger feeling again ;-)

 

It would be nice also to include temperature of the sataHat in the script, but I cannot find it. Is it measured and if yes, where is it available ?

 

Edited by JackR
Link to comment
Share on other sites

I improve the script, so now cpu and gpu as well as the 4 disks temperatures are taken into account to drive the fan speed.

Also if the fan is idle, it will always first start full speed and then adjust, to ensure it really turns. Otherwise with low duty, it may stay blocked due to mechanical friction.

 

Because of the use of smartctl to read disk temperature, it must works with elevated privileges, else only cpu and gpu temperatures are considered. The "-n standby" option avoid to spin up a disk if it is stopped. In which case, anyway, it does not need to be cooled :P

Of course smartctl must be installed. But who is crazy enough to run a nas without it :wacko:

 

#!/bin/bash

###########################################################################
# A simple bash script to run and control the NanoPi M4 SATA hat PWM1 fan #
###########################################################################

# Modified from mar0ni's script:
# https://forum.armbian.com/topic/11086-pwm-fan-on-nanopi-m4/?tab=comments#comment-95180

# Export pwmchip1 that controls the SATA hat fan if it hasn't been done yet
# This will create a 'pwm0' subfolder that allows us to control various properties of the fan
if [ ! -d /sys/class/pwm/pwmchip1/pwm0 ]; then
    echo 0 > /sys/class/pwm/pwmchip1/export
fi
sleep 1
while [ ! -d /sys/class/pwm/pwmchip1/pwm0 ];
do
    sleep 1
done

# Set default period (40000ns = 25kHz)
echo 40000 > /sys/class/pwm/pwmchip1/pwm0/period

# The default polarity is inversed. Set it to 'normal' instead.
echo normal > /sys/class/pwm/pwmchip1/pwm0/polarity

# CPU, GPU and disks temperatures to monitor
declare -a CpuTemps=(75000 68000 60000 50000 40000)
declare -a DiskTemps=(55 50 45 40 35)
# Duty cycle for each temperature range
declare -a DutyCycles=(40000 9000 3500 2200 2050)
# Change the following if you want the script to change the fan speed more/less frequently
timeStep=5

# Run fan at full speed for some seconds when the script starts, then keep running at calculated speed
echo ${DutyCycles[0]} > /sys/class/pwm/pwmchip1/pwm0/duty_cycle
echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable
sleep $timeStep

# Main loop to monitor cpu (zone0) and gpu (zone1) temperatures, as well as NAS hard disks temperatures
# and assign duty cycles accordingly. Disks device name must be adapted to your own case (/dev/sdX).
# The -n option of smartctl avoid to spin up a disk if it has stopped
while true
do
    temp0=$(cat /sys/class/thermal/thermal_zone0/temp)
    temp1=$(cat /sys/class/thermal/thermal_zone1/temp)
    test $temp0 -gt $temp1 && tempU=$temp0 || tempU=$temp1
    tempD=0
        temp2=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sda | grep -m 1 Temperature | awk '{print $3}'`
    if [ -n "$temp2" ]; then
        tempD=$temp2
    fi
    temp3=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sdb | grep -m 1 Temperature | awk '{print $3}'`
    if [ -n "$temp3" ]; then
               test $temp3 -gt $tempD && tempD=$temp3
    fi
    temp4=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sdc | grep -m 1 Temperature | awk '{print $3}'`
    if [ -n "$temp4" ]; then
               test $temp4 -gt $tempD && tempD=$temp4
    fi
    temp5=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sdd | grep -m 1 Temperature | awk '{print $3}'`
    if [ -n "$temp5" ]; then
               test $temp5 -gt $tempD && tempD=$temp5
    fi
    duty0=$(cat /sys/class/pwm/pwmchip1/pwm0/duty_cycle)
    DUTY=0
    # If you changed the length of $CpuTemps and $DutyCycles, then change the following length, too
    for i in 0 1 2 3 4; do
        # add some hysteresis when the fan speeds down to avoid continuous stop and go
        test $duty0 -ge ${DutyCycles[$i]} && j=2 || j=0
        if [ $tempU -gt $((${CpuTemps[$i]}-$j*1000)) ] || [ $tempD -gt $((${DiskTemps[$i]}-$j)) ]; then
            # if the fan is stopped, first full speed to ensure it really starts
            test $duty0 -eq 0 && DUTY=${DutyCycles[0]} || DUTY=${DutyCycles[$i]}
            # To test the script, uncomment the following line:
            # echo "i: $i, j: $j, cpu: $temp0, gpu: $temp1, target: ${CpuTemps[$i]}; d1: $temp2, d2: $temp3, d3: $temp4, d4: $temp5, target: ${DiskTemps[$i]}, duty: $DUTY"
            break        
        fi
    done
    echo $DUTY > "/sys/class/pwm/pwmchip1/pwm0/duty_cycle";
    sleep $timeStep;
done

exit 0

 

I also write a small script to display temperatures and duty at a will. It too must be run with sudo in order to be able to see disk temperature.

 

#! /bin/bash
# NAS temperatures monitoring
temp0=$(cat /sys/class/thermal/thermal_zone0/temp)
temp1=$(cat /sys/class/thermal/thermal_zone1/temp)
temp2=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sda | grep -m 1 Temperature | awk '{print $3}'`
temp3=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sdb | grep -m 1 Temperature | awk '{print $3}'`
temp4=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sdc | grep -m 1 Temperature | awk '{print $3}'`
temp5=`/usr/sbin/smartctl -l scttempsts -d sat -n standby /dev/sdd | grep -m 1 Temperature | awk '{print $3}'`

duty0=$(cat /sys/class/pwm/pwmchip1/pwm0/duty_cycle)
echo "cpu: $temp0, gpu: $temp1; d1: $temp2, d2: $temp3, d3: $temp4, d4: $temp5, duty: $duty0 "

 

Enjoy

Link to comment
Share on other sites

@i5Js

Sorry, I forgot to mention that I use a nanoPi M4V2, with the massive heat sink, 4 ports sataHat and emmc 32 GB from FriendlyArm. As mentionned in my 1st post I exchanged the standart sataHat small heat sink by a much bigger one, and the whole homemade case is cooled by a 12 cm, 12 V 2.2 W fan plugged on the sataHat fan socket and driven by the pwm script.

 

Link to comment
Share on other sites

@hinkley : surprising as my nanopi M4V2 is running under buster server, last version (I last update 2 days ago).

As explained at the beginning of the script I posted on Oct. 7th, some subfolders are created by the script if they don't exist. May be check again, also the link I gave to Carlos Gomes git (see my post from Sept 29th).

Link to comment
Share on other sites

Hi guys,

This topic is very old now, but maybe someone has time to help me to find the issue with a fan for SATA HAT. I was using simple 5V fan for more than year, attached to 40-pin. Now I bought 12v fan and want to have more control via PWM, but fan does not respond. I have NanoPi M4 version 1 with legacy kernel 4.4 (buster), and implemented script from here:
https://github.com/cgomesu/nanopim4-satahat-fan

I have tried other scripts, but nothing works. I guess it doesn't really matter, which one I use when I finally can make that fan work. 

Things I have tried:
- fan works fine, I have tried it with direct 12v and 9v supplies, it is the cheapest one (bought here https://www.aliexpress.com/item/32603431500.html?spm=a2g0s.9042311.0.0.25e04c4dySdv9o)
- removed SATA HAT and tried to get signal from PWM pin to my 5V fan - nothing

- the file tree for `/sys/class/pwm/pwmchip1/` looks normal after I export PWM0:

├── device -> ../../../ff420010.pwm
├── export
├── npwm
├── power
│   ├── async
│   ├── autosuspend_delay_ms
│   ├── control
│   ├── runtime_active_kids
│   ├── runtime_active_time
│   ├── runtime_enabled
│   ├── runtime_status
│   ├── runtime_suspended_time
│   └── runtime_usage
├── pwm0
│   ├── capture
│   ├── duty_cycle
│   ├── enable
│   ├── period
│   ├── polarity
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   └── uevent
├── subsystem -> ../../../../../class/pwm
├── uevent
└── unexport

 

 

- I have tried different numbers for duties. And there are no errors, when script writes  to duty_cycle.

 

I am a bit lost. Maybe someone more experienced can have a look at the logs and spot some missing setup. It would be nice to get this new 12V fan up and running. My 5V fan is pretty noisy. 

 

Here is the log from `armbianmonitor`

http://ix.io/3uv0

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines