CALENTAMIENTO DE LA RASPBERRY
¿Cómo
resolver el problema de calentamiento de la RASPBERRY PI?
La respuesta es
fácil: enfriando. Para ello precisaremos de un ventilador, de los
muchos que se venden en el mercado, por ejemplo éste.
El problema de este
sistema es que aumenta el consumo y hace un cierto ruido puesto que
funciona siempre.
Para evitarlo os proponemos un pequeño montaje
que, junto a un software escrito en python, que es un lenguaje que lleva incorporada la Raspberry, provee un control
variable del ventilador, funcionando solamente al régimen necesario
para enfriar la Raspberry, sin necesidad de poner el ventilador a
plena potencia, a no ser que estéis en un ambiente muy caliente.
Hardware
Haremos un circuito
regulador con los componentes siguientes:
placa protoboard
1 resistencia de 470
ohmnios
1 diodo (cualquier
tipo, incluido un LED)
1 transistor BC548
(sirve cualquier NPN)
1 ventilador
cable para conexión
El esquema es el
siguiente
La señal de control
del ventilador vendrá de uno de los pins del conector GPIO de la
Raspberry. Sirve cualquiera, en nuestro caso hemos usado el pin
GPIO17 que corresponde al terminal 11 del conector GPIO mientras que
la alimentación (5v) proviene del pin 2 y la masa del pin 6. El pin
GPIO puede ser cambiado por otro sin mayor dificultad, modificando la constante definida en el programa.
El funcionamiento es
extremadamente simple:
Cuando en la entrada
CTRL se aplica una tensión positiva, es decir un nivel alto, que en
la RASPBERRY PI corresponde a 3.3 v el transistor se pone a conducir
y el ventilador se activa. Cuando la tensión de control es 0v el
transistor se bloquea y no conduce, y el ventilador se para.
A base de conducir y
bloquear, rápidamente , se puede generar una señal de salida pulsada, con pulsos de anchura variable. Es decir, se puede generar, por software, un control de velocidad
basado en variar la anchura de los pulsos. Por ejemplo, si trabajamos
una frecuencia de 100 Hz (100 pulsos por segundo, con un período de período de 10
milisegundos ), si los pulsos son de anchura 10 ms estaremos
alimentando al 100%, es decir a velocidad máxima, si los pulsos son
5 ms estaremos al 50% y así sucesivamente.
Así pues,
implementaremos un control PWM por software.
Software
Hemos utilizado el
lenguaje python3 porque ya viene instalado en la Raspberry, junto con
el sistema operativo. Y dentro del programa, hemos querido utilizar
“hilos” (“threads” en inglés) para practicar con la
multitarea que nos permite python.
Código fuente
(fan.py)
#!/usr/bin/python3
#
librerias
from
threading import Thread
from
time import *
import
RPi.GPIO as GPIO, atexit
from
subprocess import getoutput
duty=0
# ciclo del PWM para ventilador valor inicial
ta=[]
# fifo de temperaturas
lenfifo=4
# fifo de medidas de temperatura
PIN=17
# puede ser cualquier pin
frecuencia=100
# Veces que se actualiza la velocidad del ventilador.
# A más frecuencia mayor uso de CPU.
dutymin=15
# ciclo minimo. A determinar experimentalmente,
#
a partir de qué valor el ventilador se para
tCenter=60
# temperatura central
tDelta=5
# semi intervalo de control
#
parada ordenada del programa
def
parada():
global
Run,duty
duty=0
Run=False
GPIO.setup(PIN,GPIO.OUT)
GPIO.output(PIN,GPIO.LOW)
GPIO.cleanup()
return
#--------------------------------------------------
#
gestión soft de la velocidad del ventilador mediante variación del
ancho de pulso de tensión aplicada
def
fan():
global
duty
d=duty
GPIO.setup(PIN,GPIO.OUT)
while
Run:
d=duty
if
duty>100:
d=100
duty=100
if
duty<dutymin:
d=0
if
Run:
GPIO.output
(PIN,GPIO.HIGH)
sleep(d/100/frecuencia)
if
Run:
GPIO.output
(PIN,GPIO.LOW)
sleep((100-d)/100/frecuencia)
GPIO.output
(PIN,GPIO.LOW)
return
#
leer temperatura CPU y GPU y retornar la mayor de las dos,
#
promediado de n medidas (en fifo ta)
def
get_temp():
global
ta
#
temperatura GPU
gpu_temp
= float(getoutput('/opt/vc/bin/vcgencmd measure_temp' ).replace(
'temp=', '' ).replace( "'C", '' ))
#
temperatura CPU
tempFile
= open( "/sys/class/thermal/thermal_zone0/temp" )
t1=int(tempFile.read())/1000.0
tempFile.close()
#
poner en fifo la mayor de las dos
ta.append(max(gpu_temp,t1))
if
len(ta)>lenfifo:
ta=ta[1:]
#
calcular la media de las últimas medidas
cpu_temp
= 0
for
i in range (len (ta)):
cpu_temp+=ta[i]
cpu_temp
= cpu_temp/len(ta)
return
cpu_temp
#determina
el valor de duty en función de la temperatura
#
si T< t0-dt duty =0
#
si T> t0+dt duty =100
#
si t0-dt<T< t0+dt duty: interpolacion lineal
def
controlfan():
global
duty
dmin=dutymin
t0=tCenter
dt=tDelta
while
True:
t=get_temp()
if
t<(t0-dt):
duty=0
elif
t>=(t0+dt):
duty=100
else:
#
lineal entre T0-dt (30%=cnf["FAN"]["DUTYMIN"]) i
t0+dt(100%)
duty=(100-dmin)/2*(t-t0+dt)/dt+dmin
sleep
(0.5)
#-------------------------------------
#
Modulo principal
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
atexit.register
(parada)
#
Inicialitzación variables y processos
Run=True
ventilador=Thread(target=fan,daemon=True)
ventilador.start()
controlven=Thread(target=controlfan,daemon=True)
controlven.start()
#
bucle principal
while
True:
try:
sleep
(10)
except:
Run=False
Posibles
modificaciones o ajustes
El programa está
basado en dos procesos (threads) concurrentes.
Uno (controlfan), mide
la temperatura y determina el porcentaje del ciclo (duty) que estará
ON y OFF, en función de la temperatura.
La temperatura se
mide en la CPU y la GPU y se toma la mayor de las dos (caso más
desfavorable)Ñ los valores se acumulan en una lista FIFO y se
promedian. En nuestro caso se usan 4 valores (lenfifo) pero se
puede aumentar el valor sin problemas. Esto evita que los cambios
sean bruscos por variaciones puntuales o errores de medida. Es lo que
podemos llamar un filtro pasa-bajo.Tampoco es conveniente ponerlo muy grande porque hace que la respuesta a una variación de temperatura sea más lenta.
Si el valor de la
temperatura esta por debajo de tCentral-tDelta (en nuestro caso
serían 55º) el ventilador está parado. Al pasar de este punto el
ventilador empieza a funcionar. El arranque no se hace desde cero
puesto que, por la inercia del motor se requiere un poco más de par
para poder arrancar. Así pues, duty parte de 15 (dutymin), valor que
se puede determinar experimentalmente y que es tanto menor como alta
es la frecuencia.
Aquí aparece otro factor, la frecuencia. Si la
frecuencia es muy alta, la regulación es mejor pero, se consume más
recursos de CPU. Una frecuencia de 100 Hz da buenos resultados en
todos los casos pero podéis probar con otros valores.
Entre
tCentral-tDelta (55º) y tCentral+tDelta (65º) tenemos una
regulación lineal. proporcional a la diferencia de temperatura respecto al mínimo (55 º).
A partir de tCentral+tDelta (65º) el ventilador
va al 100%, al màximo.
Los valores de
tCentral y tDelta pueden ser modificados, experimentando como va la
regulación y el ruido generado por el ventilador.
Puesta en
marcha
El sistema se puede
poner en marcha manualmente tecleando
python3 fan.py
en una terminal del
sistema
Mejor solución es
ejecutar-lo en background, tecleando
python3 fan.py &
Y mucho mejor
incluirla en la tabla de cron, para que arranque automàticamente al
arrancar el sistema. pero eso es otro tema ...
Resultados
La placa utilizada ,
en algunos casos había llegado a bloquearse por exceso de
temperatura antes de poner el ventilador.
Al poner un ventilador sin
regulación, el problema desaparecía pero el ruido se hacía bastante
molesto al cabo de un rato, sobre todo si se trabaja en un ambiente
silencioso. Con este sistema quedan resueltos ambos problemas.
Espero vuestros
comentarios
Comentarios
Publicar un comentario