Skip to main content

Seguendo questo tutorial sarai in grado di assemblare una ventola su un Raspberry Pi e utilizzando un transistor potrai controllarne l’accensione e lo spegnimento. Poi dovrai scrivere uno script in Python per attivare la ventola quando la CPU raggiunge una certa temperatura. Infine, sarai in grado di eseguire lo script automaticamente al momento dell’avvio.

Campo d’Applicazione

Uso il Raspberry Pi 3 per un sacco di cose. PiHole è una di queste (Ho in programma una guida su come installarlo). L’RPI3 è molto veloce nell’elaborare le richieste ma e viene messo sotto stress fatica anche lui, e non poco. Qualsiasi sia l’utilizzo del raspberry è buona norma dissipare il calore in eccesso proveniente dalla CPU che in qualche raro caso mi ha raggiunto il 380% con il conseguente aumento di temperatura. Si possono raggiungere tranquillamente gli 80°C specialmente in estate. Così ho pensato: è il momento di aggiungere un sistema di raffreddamento attivo.

Configurazione hardware del Raspberry Pi

Prima le cose importanti: ho comprato questa ventola su Amazon. Tutte le ventole che ho visto sono DC 5V con un massimo di 200mA: quindi la potenza attiva è di 1W. Tuttavia, i pin GPIO sul Raspberry possono erogare solo 3,3V con un massimo di 16mA ciascuno il che significa che non possiamo – e non dobbiamo – alimentare il motore con la potenza del pin.

Huston, abbiamo un problema.

Quello di cui abbiamo bisogno è una sorta di relè che può essere attivato da un pin standard per convogliare corrente a pieno regime alla nostra ventolina. Ed ecco che entra in gioco il transistor. Più specificamente, un transistor NPN (S8050). La configurazione finale è la seguente (la ventola è rappresentata come un motore in corrente continua anche se NON è un vero motore in corrente continua):

RPI3 Breadboard circuit
Breadboard


Schema

Non collegate MAI un vero motore a corrente continua alla vostra scheda: lo danneggerete sicuramente.

Una volta che tutto è impostato e collegato è il momento della parte software. Dobbiamo in qualche modo controllare la ventola quando la temperatura della CPU raggiunge un valore troppo alto.

Creiamo lo script Python dal nostro Raspberry

Creare un file chiamato “run-fan.py” in una posizione personalizzata (il mio è in ~/Development/RanFan/run-fan.py) e copiate-incollate il seguente codice (Il codice lo puoi scaricare anche dalla mia repo GitHub):

#!/usr/bin/env python3
# Author: Enrico Bez 
import os
from time import sleep
import signal
import sys
import RPi.GPIO as GPIO
import datetime
pin = 14 # Identificativo del pin
maxTMP = 70 # La temperatura massima in gradi Celsius oltre la quale si attiva la ventola
superTMP = 77 # La temperatura estrema in gradi Celsius oltre la quale si attiva la ventola per più tempo
# Funzione per il setup delle porte GPIO
def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin, GPIO.OUT)
    GPIO.setwarnings(False)
    loggingACC() # Funzione per logging all'accensione del Raspberry
    return()
# Funzione per ottenere il valore delle temperatura si sistema della CPU
def getCPUtemperature():
    res = os.popen('vcgencmd measure_temp').readline()
    temp =(res.replace("temp=","").replace("'C\n",""))
    deg = u'\xb0'  # utf code for degree
    deg = deg.encode('utf8')
    # print("temp is {0}".format(temp) + deg) # Scommenta per test 
    return temp
# Funzione per logging all'accensione del Raspberry
def loggingACC():
    now=datetime.datetime.now()
    with open("/home/pi/Development/RunFan/fan.log", mode='a') as file:
        deg = u'\xb0'  # utf code for degree
        deg = deg.encode('utf8')
        file.write('------------------ SISTEMA AVVIATO ------------------\n%s: Temperatura = %s%s\n' %(now.strftime("%d-%m-%Y %H:%M:%S"),getCPUtemperature(),deg))
        file.close()
# Funzione per logging all'accensione della ventola
def loggingON():
    now=datetime.datetime.now()
    with open("/home/pi/Development/RunFan/fan.log", mode='a') as file:
        deg = u'\xb0'  # utf code for degree
        deg = deg.encode('utf8')
        file.write('%s: Temperatura = %s%s Ventola ON\n' %(now.strftime("%d-%m-%Y %H:%M:%S"),getCPUtemperature(),deg))
        file.close()
# Funzione per logging allo spegnimento della ventola
def loggingOFF():
    now=datetime.datetime.now()
    with open("/home/pi/Development/RunFan/fan.log", mode='a') as file:
        deg = u'\xb0'  # utf code for degree
        deg = deg.encode('utf8')
        file.write('%s: Temperatura = %s%s Ventola OFF\n' %(now.strftime("%d-%m-%Y %H:%M:%S"),getCPUtemperature(),deg))
        file.close()
# Funzione per logging all'accensione della ventola nel caso di temperature molto alte
def loggingSUPER():
    now=datetime.datetime.now()
    with open("/home/pi/Development/fan.log", mode='a') as file:
        deg = u'\xb0'  # utf code for degree
        deg = deg.encode('utf8')
        file.write('%s: Temperatura = %s%s Ventola ON (SUPER MODE)\n' %(now.strftime("%d-%m-%Y %H:%M:%S"),getCPUtemperature(),deg))
        file.close()
# Funzioni per la gestione della ventola
def fanON():
    setPin(True)
    loggingON()
    sleep(90) # La ventola va per 90 secondi
    loggingOFF()
    return()
def fanSUPER():
    setPin(True)
    loggingSUPER()
    sleep(150) # La ventola va per 150 secondi
    loggingOFF()
    return()
def fanOFF():
    setPin(False)
    sleep(10) # La ventola si spegne per 10 secondi
    return()
# Algoritmo di esecuzione principale da cui richiamo le varie funzioni
def getTEMP():
    CPU_temp = float(getCPUtemperature())
    if CPU_temp>maxTMP and CPU_tempsuperTMP:
        fanSUPER()
    else:
        fanOFF()
    return()
def setPin(mode): # Una funzione un po' ridondante ma utile se si vuole aggiungere il logging
    GPIO.output(pin, mode)
    return()
    
try:
    setup() 
    while True:
        getTEMP()
        sleep(5) # Leggere la temperatura ogni 5 sec, aumentare o diminuire questo limite se si desidera
except KeyboardInterrupt: # Serve per intrappolare l'interrupt da tastiera CTRL+C 
    GPIO.cleanup() # resetta tutte le porte GPIO utilizzate da questo programma

Ok, ora proviamo dalla console:

Eseguiamo lo script Python per verificarne la corretta esecuzione

python3 run-fan.py

Se tutto è stato impostato correttamente si dovrebbe vedere la ventola che gira e si ferma in base alla temperatura della CPU.

Un’ultima cosa

Ovviamente non vogliamo eseguire manualmente il programma ogni volta che riavviamo il nostro RaspberryPi, vero? L’ideale sarebbe che venga eseguito in automatico all’avvio, giusto? Allora creiamo uno script di avvio che farà partire a sua volta lo script Python:

#!/bin/sh
# launcher.sh
# Naviga verso la directory corrente, eseguire lo script python, poi torna a casa

cd /home/pi/Development/RunFan
sudo python2 run-fan.py
cd /

Ora impostiamo un cronjob per l’esecuzione automatica all’avvio:

sudo crontab -e

Ora inserisci la seguente riga:

@reboot sh /home/pi/Development/RunFan/launcher.sh > /home/pi/logs/cronlog 2>&1 

Riavviamo il RaspberryPi

sudo reboot

All’avvio possiamo controllare nella cartella dove avete deciso di salvare i file di log se ci sono errori con il cronjob. Se tutto è andato senza errori, la prima volta che la CPU raggiungerà una temperatura elevata, il vostro script verrà eseguito automaticamente. Come test iniziale ho impostato una temperatura di soglia bassa così da far eseguire lo script quasi sicuramente pochi secondi dopo l’avvio. Finita la fase di test tornate ad un valore di temperatura ragionevole e riavviate il raspberry.

Questa guida l’ho sviluppata lavorando su un Raspberry Pi 3 ma è molto probabile che funzioni anche per il Raspberry Pi 4 che consiglio di acquistare al posto della versione 3.

Ti è piaciuto l’articolo? Condividilo con i tuoi amici!