Domare la ventola del Raspberry con transistor e resistenze

ventola raspberry pi 4

Nella foto, c’è una ventola collegata in modo strano alla board del RaspBerry. Tutto quel macello permette di avviare automaticamente la ventola quando la temperatura della CPU raggiunge la temperatura impostata (io ho messo 55°C). Perché questo?

  • Il RaspBerry Pi 4 tende a surriscaldarsi avendo un processore molto più potente del precedente modello, controllare la temperatura della CPU permette di evitare anche il calo di prestazioni dovute al throttling.
  • Utilizzandolo spesso collegato con l’iPad, la ventola da 5V rimarrebbe sempre accesa in quanto il pin da 5V non è controllabile via software, riceve energia direttamente dall’alimentatore. Il problema non è solo il rumore (sembra di avere vicino un elicottero), ma anche il battery drain dovuto all’assorbimento della ventola.

Che cosa serve

Il progetto prevede l’utilizzo di un transistor NPN 2N222 e di una resistenza, io ho utilizzato un resistore da 1k ohm, ma già da 500 ohm va bene. Li trovate tranquillamente su Amazon. Ovviamente serve una ventola, vi consiglio di acquistare direttamente il Raspberry in kit con già la ventola in dotazione.

I collegamenti della ventola

Lo schema dei collegamenti. Il cavo positivo della ventola va collegato direttamente al Raspberry sul pin da 5V, il negativo invece deve essere collegato sul collettore del transistor 2N222.

Come si vede dallo schema sopra, il cavo positivo della ventola va collegato direttamente al pin 5V del Raspberry, il negativo invece va collegato sul collettore del transistor. Sull’emettitore del transistor va collegato il cavo che poi finirà sul pin ground dell’interfaccia GPIO. Sul Base del transistor invece bisogna collegare il cavo che all’altra estremità finisce sul pin GPIO17. Questo pin possiamo controllarlo via software. Su quest’ultimo cavo bisogna mettere una resistenza da almeno 500ohm per evitare che la tensione del pin GPIO17 a 3,3v frigga il transistor.

In questo schema il transistor riceve energia sul collettore. Quando sulla base del transistor arriva corrente, l’emettitore si attiva e il circuito viene chiuso facendo avviare la ventola. In poche parole si tratta di un AND quando C (Collettore) e B (Base) sono veri anche l’E (Emettitore) è vero.

Con il comando pinout potete vedere lo schema del vostro raspberry

implementazione del software

Creiamo il file fancontrol.py con il seguente contenuto

#!/usr/bin/env python3

import subprocess
import time

from gpiozero import OutputDevice


ON_THRESHOLD = 55  # (degrees Celsius) Fan kicks on at this temperature.
OFF_THRESHOLD = 45  # (degress Celsius) Fan shuts off at this temperature.
SLEEP_INTERVAL = 5  # (seconds) How often we check the core temperature.
GPIO_PIN = 17  # Which GPIO pin you're using to control the fan.


def get_temp():
    """Get the core temperature.
    Run a shell script to get the core temp and parse the output.
    Raises:
        RuntimeError: if response cannot be parsed.
    Returns:
        float: The core temperature in degrees Celsius.
    """
    output = subprocess.run(['vcgencmd', 'measure_temp'], capture_output=True)
    temp_str = output.stdout.decode()
    try:
        return float(temp_str.split('=')[1].split('\'')[0])
    except (IndexError, ValueError):
        raise RuntimeError('Could not parse temperature output.')


if __name__ == '__main__':
    # Validate the on and off thresholds
    if OFF_THRESHOLD >= ON_THRESHOLD:
        raise RuntimeError('OFF_THRESHOLD must be less than ON_THRESHOLD')

    fan = OutputDevice(GPIO_PIN)

    while True:
        temp = get_temp()

        # Start the fan if the temperature has reached the limit and the fan
        # isn't already running.
        # NOTE: `fan.value` returns 1 for "on" and 0 for "off"
        if temp > ON_THRESHOLD and not fan.value:
            fan.on()

        # Stop the fan if the fan is running and the temperature has dropped
        # to 10 degrees below the limit.
        elif fan.value and temp < OFF_THRESHOLD:
            fan.off()

        time.sleep(SLEEP_INTERVAL)

Spostiamo il file nella cartella /usr/local/bin e settiamo i permessi per eseguirlo

sudo mv fancontrol.py /usr/local/bin/ 
sudo chmod +x /usr/local/bin/fancontrol.py

Per rendere eseguibile lo script al boot, creiamo il file fancontrol.sh e inseriamo le seguenti righe

#! /bin/sh

### BEGIN INIT INFO
# Provides:          fancontrol.py
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting fancontrol.py"
    /usr/local/bin/fancontrol.py &
    ;;
  stop)
    echo "Stopping fancontrol.py"
    pkill -f /usr/local/bin/fancontrol.py
    ;;
  *)
    echo "Usage: /etc/init.d/fancontrol.sh {start|stop}"
    exit 1
    ;;
esac

exit 0

Spostiamo il file appena creato in /etc/init.d con i permessi per eseguirlo

sudo mv fancontrol.sh /etc/init.d/
sudo chmod +x /etc/init.d/fancontrol.sh

Registriamo lo script per l’esecuzione all’avvio

sudo update-rc.d fancontrol.sh defaults

Riavviamo il raspberry.

Una volta riavviato, spremiamolo per bene, magari guardando qualche video su Youtube e attendiamo che la CPU raggiunga la soglia di temperatura impostata. Se tutto è configurato a dovere la ventola dovrebbe partire automaticamente appena la CPU raggiungerà i gradi impostati.

Precedente Raspberry pi 4, collegamento iPad via usb-c ethernet Successivo Wifi over ethernet, condividere la connessione con raspberry