
La Raspberry Pi 4 es una bestia del rendimiento, si la dejas trabajar duro, su procesador puede alcanzar temperaturas que activan el thermal throttling, reduciendo su velocidad para no «derretirse». Es fundamental entender que el procesador empieza a reducir su velocidad automáticamente cuando llega a los 80°C – 85°C para protegerse.
Muchos optan por conectar un ventilador directamente a los pines de 5V, lo cual funciona, pero tiene dos grandes problemas: el ruido constante (¡parece un avión despegando!) y el desgaste innecesario del motor.
En esta entrada, vamos a hacer algo mucho más elegante y profesional. Vamos a configurar un sistema de control por PWM (Modulación por Ancho de Pulsos) utilizando el tercer cable de nuestro ventilador. ¿Qué conseguiremos con esto?
- Silencio absoluto: El ventilador solo girará lo necesario.
- Inteligencia térmica: Crearemos un script en Python que «lee» la mente (y la temperatura) de la CPU.
- Automatización total: Configuraremos un servicio en Linux para que el control sea eterno y arranque solo.
- Protección de hardware: Evitaremos forzar los pines de la placa con una configuración segura.
Si quieres que tu Pi 4 esté siempre fresca sin sacrificar tus oídos, ¡acompáñame en este tutorial!
Conexión del ventilador
Un ventilador PWM (Modulación por Ancho de Pulsos) se compone de 3 cables, esto significa que no solo puedes encenderlo o apagarlo, sino que puedes regular su velocidad (por ejemplo, que gire al 40% si está a 45°C y al 100% si llega a 60°C).
La función de cada cable es:
- Rojo a un pin de 5V positivo. (Pin 2 o 4). Aquí toma la fuerza.
- Negro a un pin GND negativo. (Pin 6).
- Azul (PWM) por ejemplo, pin 18 (GPIO 24).

Como se ve en la imagen anterior, No, se necesita resistencia, ya que el cable azul solo recibe una «señal» de control de muy baja intensidad (lógica), el procesador de la Raspberry no sufre. El transistor ya viene integrado dentro del propio ventilador para gestionar esa señal.
Nota: Algunos ventiladores baratos de 3 cables no soportan PWM por el tercer cable (a veces el tercer cable es solo un sensor de revoluciones, no de control).
– Si el ventilador baja de velocidad: ¡Perfecto! Todo funciona.
– Si el ventilador solo está encendido o apagado: Significa que tu cable azul es un sensor «Tacho» y no admite control de velocidad. En ese caso, el script funcionará a todo o nada. (ON/OFF).
El script.
Con este script, tu Raspberry Pi 4 tendrá un comportamiento idéntico al ventilador de un ordenador portátil moderno. Este no solo enciende o apaga, sino que hace que el ventilador «susurre» cuando hay poca temperatura y «sople» fuerte solo cuando es necesario.
Script (Edición PWM)
Copia y pega el siguiente script en un archivo llamado fanGuard.py
nano fanGuard.py
#!/usr/bin/python3
import RPi.GPIO as GPIO
import time
import sys
from datetime import datetime
# ==========================================
# CONFIGURACIÓN PROPORCIONAL
# ==========================================
PIN_FAN = 18
FRECUENCIA = 100
ESPERA = 3
TEMP_ARRANQUE = 45
TEMP_MAXIMA = 60
TEMP_PARADA = 39
POTENCIA_MIN = 40
# ==========================================
def obtener_temp():
try:
with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
return float(f.read()) / 1000
except Exception:
return 0
# Inicialización de GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN_FAN, GPIO.OUT)
pwm = GPIO.PWM(PIN_FAN, FRECUENCIA)
pwm.start(0)
ventilador_activo = False
print("="*45)
print("🌀 CONTROL DINÁMICO PROPORCIONAL")
print(f"Rango: {TEMP_PARADA}°C (OFF) <-> {TEMP_MAXIMA}°C (100%)")
print("="*45)
try:
while True:
temp = obtener_temp()
ahora = datetime.now().strftime("%H:%M:%S")
nivel = 0 # <--- Inicializamos aquí para evitar el error NameError
# 1. Lógica de activación con Histéresis
if temp >= TEMP_ARRANQUE:
ventilador_activo = True
elif temp <= TEMP_PARADA:
ventilador_activo = False
# 2. Si está activo, calculamos velocidad dinámica
if ventilador_activo:
if temp >= TEMP_MAXIMA:
nivel = 100
else:
dif_temp = temp - TEMP_ARRANQUE
rango_temp = TEMP_MAXIMA - TEMP_ARRANQUE
rango_potencia = 100 - POTENCIA_MIN
nivel = POTENCIA_MIN + (dif_temp * rango_potencia / rango_temp)
nivel = int(nivel)
else:
nivel = 0
# Aplicar el Duty Cycle al PWM
pwm.ChangeDutyCycle(min(max(nivel, 0), 100))
# Feedback visual (usa print para que se vea bien en journalctl)
estado = "🌀" if ventilador_activo else "💤"
barra = "█" * (nivel // 10) + "░" * (10 - (nivel // 10))
print(f"[{ahora}] {estado} Temp: {temp:.1f}°C | Potencia: [{barra}] {nivel}%")
time.sleep(ESPERA)
except KeyboardInterrupt:
print("\n\nCerrando...")
finally:
pwm.stop()
GPIO.cleanup()
Guarda el documento con Ctrl + o y sal con Ctrl + x
No olvides hacerlo ejecutable con:
chmod +x fanGuard.py
El ciclo de vida del ventilador:
- Zona de Reposo (Hasta 45°C): El ventilador está en 0% (Apagado). Reina el silencio absoluto mientras haces tareas ligeras.
- El Despertar (A los 45°C): En el momento que el sensor marca 45.0°C, el ventilador «despierta» directamente al 40% de potencia. Esto se hace así para asegurar que el motor tenga fuerza suficiente para empezar a girar (romper la inercia).
- Zona Dinámica (De 45°C a 60°C): Aquí es donde ocurre la magia. El script calcula la potencia grado a grado:
- Si sube a 50°C $\rightarrow$ El ventilador sube automáticamente a un 60% aprox.
- Si sube a 55°C $\rightarrow$ El ventilador sube a un 80% aprox.
- Zona de Pánico (60°C o más): El ventilador se pone al 100% (Máxima velocidad) para evacuar el calor lo más rápido posible.
Lo más ingenioso es que el camino de vuelta es distinto:
Si el ventilador está soplando al 40% y la temperatura baja a 44°C, no se apaga. Seguirá soplando al 40% hasta que la temperatura baje de 39°C.
Esto crea una «ventana de trabajo» que evita que el motor sufra arranques y paradas constantes. (Histéresis)
Tabla resumen de revoluciones (ejemplo estimado):
| Temperatura | Estado | Potencia PWM | Ruido Estimado |
| 38°C | Bajando | 0% (Apagado) | Silencio total |
| 42°C | Subiendo | 0% (Apagado) | Silencio total |
| 45°C | Arranca | 40% | Susurro suave |
| 52°C | Estable | 68% | Flujo de aire constante |
| 60°C | Alerta | 100% | Máximo soplado |
¿Cómo saber si los porcentajes son correctos para TU ventilador?
Cada ventilador es un mundo. Si notas que al 40% hace un ruido eléctrico pero no gira, puedes subir la variable POTENCIA_MIN a 50. Si por el contrario gira muy fuerte desde el principio, puedes bajarla a 30.
Para alargar la vida útil de los componentes y mantener el máximo rendimiento, lo ideal es mantenerla por debajo de los 60°C en carga de trabajo.
Aquí tienes una guía de configuración recomendada para tu script PWM:
1. Rangos de Temperatura Recomendados
| Estado | Temperatura | Acción del Ventilador |
| Frío (Reposo) | < 39°C | 0% (Apagado). No es necesario desgastar el motor. |
| Tibio (Navegación) | 40°C – 48°C | 30% – 40%. Flujo de aire mínimo y silencioso. |
| Trabajando (Vídeo/Juegos) | 48°C – 58°C | 60% – 70%. Empieza a ser necesario extraer calor. |
| Alerta (Carga máxima) | > 60°C | 100%. Máxima potencia para evitar el throttling. |
Crear el archivo del servicio
Para hacerlo «eterno» con systemd, tenemos que seguir unos pasos específicos. Es vital que el servicio se ejecute como root (para tener permisos sobre los GPIO) y que gestione bien el apagado, evitando que el ventilador no se quede «silbando» cuando detengas la Raspberry.
Abre el editor para crear el archivo de configuración del sistema:
sudo nano /etc/systemd/system/fanGuard.service
3. Pegar la configuración del servicio
Copia y pega este bloque tal cual, sustituyendo tu_usuario, por el tuyo propio de la ruta en ExecStart):
[Unit]
Description=Control Inteligente de Ventilador PWM con Histeresis
After=multi-user.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/python3 -u /home/tu_usuario/fanGuard.py
Restart=always
RestartSec=10
# Esto asegura que los prints del script se vean en el log del sistema
StandardOutput=inherit
StandardError=inherit
[Install]
WantedBy=multi-user.target
4. Activar el «Modo Eterno»
Ahora ejecuta estos comandos en orden para que el sistema reconozca el nuevo servicio y lo arranque:
- Recargar el sistema:
sudo systemctl daemon-reload - Activar el inicio automático al arrancar:
sudo systemctl enable fanGuard.service - Iniciar el ventilador ahora mismo:
sudo systemctl start fanGuard.service
¿Cómo puedes vigilar tu ventilador ahora?
Como el script ahora corre de fondo («eterno»), ya no verás la barrita de carga directamente en la pantalla, pero puedes «espiarlo» con estos comandos:
- Para ver si está vivo y la temperatura actual:
sudo systemctl status fanGuard.service - Para ver la «barra molona» en tiempo real (ver los logs):
journalctl -u fanGuard.service -f - Si quieres detenerlo para hacer cambios en el script:
sudo systemctl stop fanGuard.service
(Al detenerlo, gracias al bloquefinallyde tu script, el ventilador se apagará completamente).
¡Listo! Ya tienes un sistema de refrigeración de grado industrial en tu Raspberry Pi 4.