nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Código Python para control temp. de CPU con Ventilador PWM

Thu Aug 18, 2016 9:39 pm

[SOLUCIONADO]

-Para Raspberry Pi 1 Model B rev.2:
Hola,
he montado un ventilador de 5v de 4 cables: GND, 5V, PWM y TACH.

El cable de Tach. lo ignoro. Parece ser que todo funciona correctamente conectando la entrada PWM del ventilador directamente a la salida PWM GPIO18 de la Raspberry Pi y con un sencillo programa, al cual le varío manualmente la velocidad para confirmar su funcionamiento.

No tengo ni idea de Python, así que este es el programa que he logrado hacer para confirmar que funciona:

Code: Select all

import RPi.GPIO as GPIO
import time #Para delays     
GPIO.setmode(GPIO.BCM) #Escojo GPIO.BCM como modo de numeración.
GPIO.setup(18, GPIO.OUT) #Configuro GPIO18
pwm = GPIO.PWM(18, 1000) #Configuro la señal PWM a una frecuencia de 1KHz.
pwm.start(50) #Configuro el ciclo de trabajo al 50%
pwm.ChangeDutyCycle(25) #Configuro la velocidad del ventilador en %
time.sleep(500) #Delay
pwm.stop() #Apagar señal PWM
GPIO.cleanup() #GARBAGE COLLECTING
Éste otro programa que encontré es para visualizar las temperaturas de la Raspberry Pi:

Code: Select all

import commands

def get_cpu_temp():
    tempFile = open( "/sys/class/thermal/thermal_zone0/temp" )
    cpu_temp = tempFile.read()
    tempFile.close()
    return float(cpu_temp)/1000
    #Mostrar temperatura en grados Fahrenheit
    #return float(1.8*cpu_temp)+32

def get_gpu_temp():
    gpu_temp = commands.getoutput( '/opt/vc/bin/vcgencmd measure_temp' ).replace( 'temp=', '' ).replace( "'C", '' )
    return  float(gpu_temp)
    #Mostrar temperatura en grados Fahrenheit
    # return float(1.8* gpu_temp)+32

def main():
    print "Temperatura CPU: ", round(get_cpu_temp())
    print "Temperatura GPU: ", round(get_gpu_temp())

if __name__ == '__main__':
    main()
y éste es mi intento de programa para integrarlo todo:

Code: Select all

import RPi.GPIO as GPIO     

import time                 

import commands

GPIO.setmode(GPIO.BCM)    

GPIO.setup(18, GPIO.OUT)    
pwm = GPIO.PWM(18, 1000)    
a = 1 #variable solo para hacer un bucle infinito con while

def get_cpu_temp():                                              #Lectura de temperatura 
    tempFile = open( "/sys/class/thermal/thermal_zone0/temp" )
    cpu_temp = tempFile.read()
    tempFile.close()
    return float(cpu_temp)/1000

pwm.start(50)

while a == 1: #bucle infinito
        time.sleep(60)

        if get_cpu_temp() <= 40:
                pwm.ChangeDutyCycle(30)        
        else:
                if get_cpu_temp() <= 50:               
                        pwm.ChangeDutyCycle(40)
                else:
                        if get_cpu_temp() <= 60:            
                                pwm.ChangeDutyCycle(55)     
                        else:
                                if get_cpu_tmp() <= 70:
                                        pwm.ChangeDutyCycle(75)
                                else:
                                        if get_cpu_tmp() <= 80:
                                                pwm.ChangeDutyCycle(85)
                                        else:
                                                if get_cpu_tmp() <= 90:
                                                     pwm.ChangeDutyCycle(100)
pwm.stop()

GPIO.cleanup()              
Agradecería ayuda, aunque el programa no me da errores no funciona correctamente, no varía la velocidad. Me vale un programa ya hecho o sugerencias de código para el mío.

Luego como podría hacer para que se ejecute al iniciar la Raspberry Pi? lo quiero usar con OSMC (KODI).

Paralelamente me parece interesante el control de la velocidad del ventilador por PID por si alguien me puede aclarar algo el tema, lo que he visto por ahí me ha liado mucho.

Gracias por la atención.

Saludos.
Last edited by nimio on Sun Aug 28, 2016 6:10 pm, edited 1 time in total.

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Fri Aug 19, 2016 1:09 am

Fijate si con "elif" funciona ya que el bucle que habias hecho tenia muchas condiciones anidadas que se estorbaban entre si. Tambien modifique el bucle infinito para que se pueda interrumpir con CTRL C, y recien alli detenga el ventilador y limpie el puerto GPIO.

Code: Select all

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import commands
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 1000)
#a = 1 #variable solo para hacer un bucle infinito con while

#Lectura de temperatura 
def get_cpu_temp():
    tempFile = open( "/sys/class/thermal/thermal_zone0/temp" )
    cpu_temp = tempFile.read()
    tempFile.close()
    return float(cpu_temp)/1000

#Iniciar PWM
pwm.start(50)

#bucle infinito
try:
    while True:
        if get_cpu_temp() <= 40:
                pwm.ChangeDutyCycle(30)      
        elif get_cpu_temp() <= 50:    
                pwm.ChangeDutyCycle(40)
        elif get_cpu_temp() <= 60:  
                pwm.ChangeDutyCycle(55)
        elif get_cpu_tmp() <= 70:
                pwm.ChangeDutyCycle(75)
        elif get_cpu_tmp() <= 80:
                pwm.ChangeDutyCycle(85)
        elif get_cpu_tmp() <= 90:
                pwm.ChangeDutyCycle(100)
        time.sleep(60)

except KeyboardInterrupt:
        pwm.stop()
        GPIO.cleanup()
Para iniciarlo automaticamente se podria hacer con cron.
Si OSMC tiene acceso por terminal, tendrias que ejecutar:
crontab -e
y agregar al final

Code: Select all

@reboot sudo python /home/pi/programa.py
presionar CTRL X y darle Y o S (dependiendo del idioma)
y reiniciar...

Slds!
Last edited by actkk2000 on Tue Aug 23, 2016 6:19 am, edited 1 time in total.
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Fri Aug 19, 2016 9:00 pm

Hola,

Genial, muchas gracias por responder, estoy probándolo y parece que funciona pero estoy poniéndolo a prueba.

Para notar el cambio de velocidad he puesto la velocidad al máximo si pasaba de 50 grados pero por error he hecho la modificación en si pasaba de 60 grados y al pasar de 50 grados (51 concretamente) se ponía al máximo (cuando debería ponerse al 40%).

Tengo dudas con la instrucción elif, si un elif se cumple (el primero ejecutado que se cumpla)... ignora los siguientes elif en cada repetición del bucle hasta que deje de cumplirse? por que conforme avance en el bucle la temperatura actual siempre será más pequeña que la propuesta por la condición elif siguiente y podría dar conflicto, no sé si me explico:

Si por ejemplo la temperatura actual es 50 cumpliría el primer elif por que la temperatura es más pequeña o igual a 50 pero también cumpliría el segundo elif por que la temperatura es más pequeña o igual a 60.

Se podría incluir una acotación del estilo "si la temperatura es más grande o igual a 50 y más pequeña o igual a 60"? como sería? En principio esto solucionaría este conflicto que planteo suponiendo que esté en lo cierto. No sé si sería la solución adecuada.

Saludos.

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Fri Aug 19, 2016 10:56 pm

Cada 60 segundos se repite el bucle asi que va linea por linea comparando el valor de temperatura con la condicion que le hayas puesto, y cuando se cumple una condicion ejecuta lo que le hayas indicado y sigue con la siguiente linea.
Podrias probar reducir el tiempo de espera y también hacer las comparaciones por rango agregando "mayor o igual" (>=) con "and", seria cuestion de ir probando ;)

Code: Select all

if get_cpu_temp() >= 50 and get_cpu_temp() <= 60:
Slds!
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Tue Aug 23, 2016 4:21 am

Hola, he de decir que ha funcionado perfecto, éste es el código final:

Code: Select all

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import commands
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 1000)
#a = 1 #variable solo para hacer un bucle infinito con while

#Lectura de temperatura 
def get_cpu_temp():
    tempFile = open( "/sys/class/thermal/thermal_zone0/temp" )
    cpu_temp = tempFile.read()
    tempFile.close()
    return float(cpu_temp)/1000

#Iniciar PWM
pwm.start(50)

#bucle infinito
try:
    while True:
        if get_cpu_temp() <= 40:
                pwm.ChangeDutyCycle(30)
        elif get_cpu_temp() >= 41 and get_cpu_temp() <= 50:    
                pwm.ChangeDutyCycle(40)
        elif get_cpu_temp() >= 51 and get_cpu_temp() <= 60:  
                pwm.ChangeDutyCycle(55)
        elif get_cpu_temp() >= 61 and get_cpu_temp() <= 70:
                pwm.ChangeDutyCycle(75)
        elif get_cpu_temp() >= 71 and get_cpu_temp() <= 80:
                pwm.ChangeDutyCycle(85)
        elif get_cpu_temp() >= 81:
                pwm.ChangeDutyCycle(100)
        time.sleep(30)

except KeyboardInterrupt:
        pwm.stop()
        GPIO.cleanup()
No descarto cambiar algunas temperaturas o velocidades pero en las pruebas baratas que he hecho varía la velocidad según la temperatura (no he conseguido pasar de 57ºC), espero en el futuro poder poner la Raspberry Pi a prueba de alguna manera con más temperatura y confirmar que funciona, pero se nota que varía la velocidad.

Todo lo hice en Raspbmc pero lo tenía que portar a OSMC pero me decía que tenía problemas con RPI.GPIO, así que instalé las librerías pertinentes según este link:

https://discourse.osmc.tv/t/gpio-contro ... elp/3246/3


Tuve algunos problemas con cron y creo que era por no poner delante los 5 "*" pero antes de saberlo indagué y le di permisos de ejecución a mi archivo fanpwm.py, no sé si sería necesario pero así se ha quedado:

Code: Select all

chmod +x fanpwm.py
Si no fuera necesario (no es necesario) supongo que basta con hacer chmod -x fanpwm.py

Instalo cron:

Code: Select all

sudo apt-get install cron
En cron puse

Code: Select all

* * * * * sudo python /storage/scripts/fanpwm.py
He visto en algunas configuraciones de cron que ponen "@Reboot" delante de la instrucción y "&" al final, una vez más... fue cuando no sabía por qué me fallaba y opté por quitarlo, luego descubrí que era por los "*" y no lo probé más, de hecho no recuerdo ni para qué era :lol: (Basta con poner @reboot en lugar de los 5 asteriscos)

--------

Ahora veo que cuando hago "sudo poweroff" para apagar la RPi por SSH el ventilador se queda encendido a máxima potencia hasta que no desenchufo la alimentación, he pensado en poner un transistor que se active y desactive con un pin de 3,3V.

Mi pregunta es... hay algún pin de 5v. que se ponga a 0v. al apagar la RPi por comando? si no... hay algún pin de 3,3v. que se ponga a 0v. al apagar la RPi por comando? si no... puedo coger un pin cualquiera (por ejemplo GPIO23 o pin 16) y configurarlo en el programa como salida High o Low según quiera que conduzca o no el transistor verdad?

Por lo demás muchas gracias por tu ayuda.

Saludos.
Last edited by nimio on Wed Aug 24, 2016 4:45 am, edited 2 times in total.

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Tue Aug 23, 2016 6:26 am

Disculpa, me habia olvidado poner para cron @reboot al principio de la linea, que indica que debe cargar al iniciar :oops:
Ya lo corregi en mis indicaciones.
Respecto del apagado podrias probar "sudo halt" que deberia apagar totalmente la Raspberry, sino funciona habria que ver eso del transistor...

Slds!
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 3:19 am

Hola,

por lo visto también funcionaba con los 5 asteriscos pero he modificado cron con @reboot y todo bien, gracias.
He aprovechado para modificar un poco mi último post para hacerlo más correcto.

He probado "sudo halt" pero no funciona, así que plan B:

He visto que hay dos pins con 5v y dos pins con 3,3v pero unos de un color y otros de otro en las descripciones de pinout, no sé si significa algo, aún no he mirado con un tester si se apaga alguno al apagar la R.Pi (el que yo uso claramente no) pero ya me he metido a programar GPIO23 como salida para que dé 3,3v al transistor y me he topado con un problema:

Cómo hago para decirle al programa que he apagado la raspberry pi y, por tanto, que ponga GPIO23 en LOW (0v)???

Saludos.

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 4:20 am

Podrias probar con un programa bash que primero ponga el pin en 0 y luego apague la Raspberry:
nano apagar.sh

Code: Select all

#!/bin/bash
echo 23 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio23/direction
echo 0 > /sys/class/gpio/gpio23/value
echo 23 > /sys/class/gpio/unexport
sudo halt
CTRL X -> Yes
chmod 777 apagar.sh
Ejecutar el programa con
sudo ./apagar.sh
Slds!
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 4:48 am

Así pues cada vez que apague la raspberry pi tendría que escribir "sudo ./apagar.sh"?

Bueno... sería una opción, pero me gustaría si puede ser poder ejecutar cualquier instrucción de las típicas, ya sea "sudo reboot", "sudo poweroff", "sudo halt", etc. o cualquier comando típico de linux para apagar o reiniciar el sistema indistintamente y que por código lo detectara y activara/desactivara el pin según fuera arranque o apagado/reiniciado. O en el código que tengo hecho para el control pwm incluir esa detección (ideal), pero que el usuario no tenga por que saber instrucciones especiales más allá de las de linux.

Saludos.

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 12:18 pm

A lo sumo podrias anteponer sudo a todas las lineas dentro del script y renombrarlo a "apagar" sin extensión, asi al ejecutarlo solo habria que poner:
./apagar
Y mas facil que eso no creo que se pueda, ademas quedaria como si fuera un comando en español... :)
Yo lo tengo implementado asi, incluso con mas cosas, dentro de un menu que llama a otros comandos segun la tecla que se presione. Por ejemplo:

Code: Select all

t- Temperatura
h- HTop
r- Reiniciar
s- Apagar
q- Salir
Aunque antes de pensar en todo eso habria que probar si lo de poner el gpio 23 en 0 realmente funciona...

Slds!
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

raspdroid
Posts: 1605
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: España

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 12:52 pm

Yo creo que el mejor comando que puedes usar es shutdown que hace todo lo que los demás y puedes planificar cuando apargalo entre otras opciones http://linux.die.net/man/8/shutdown

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 6:39 pm

En realidad "halt" llama a "shutdown -h", a mi me ha dado los mejores resultados porque asi apaga totalmente la Raspberry, pero es como todo, hay que probarlo y ver como funciona en el sistema de cada uno... :)
Suerte!

Slds!
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 8:31 pm

Hola, he probado con tester y esos 4 pins (2 de 3,3v y 2 de 5v) y siempre tienen alimentación aunque se apague la R.Pi.

Probaré a hacer lo que propones y ver que tal la idea del transistor.

Mientras a ver si alguien supiera integrarlo en el código de control de pwm para poder usar los comandos habituales de linux.

O... no habría algún archivo del sistema (u otra solución) donde se pueda añadir alguna línea donde se meta la condición de que en caso de ejecutar "shutdown", "reboot", "poweroff", etc... ejecute el script "apagar.sh"? Es una idea.
Saludos

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Thu Aug 25, 2016 9:52 pm

Si es por ejecutar en Python comandos del sistema se puede hacer con "os":

Code: Select all

import os
os.system ("sudo shutdown -h now")
Pero no se bajo que condiciones harias que se active dentro del programa...
Yo supe implementar un boton de apagado en un proyecto que al pulsarlo enviaba la orden de apagar la Raspberry, lo saque de aqui:
http://www.raspberry-pi-geek.com/Archiv ... spberry-Pi -> Pagina 4 - "Listing 2 while Loop"

Slds!
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Fri Aug 26, 2016 2:55 am

Bueno el tema sería más bien detectar cuando lanzo un comando de apagar o reiniciar la R.Pi para que desactive el pin GPIO23.

Pero, acabo de caer en algo, tal vez sea mucho más sencillo que todo eso:

Creo que basta con activar el pin al arranque, por que al apagar la R.Pi automáticamente ese pin dejará de alimentar al transistor verdad? así que tema zanjado.

Ahora sólo falta probarlo.

Ya os diré.

Saludos.

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Sat Aug 27, 2016 10:14 pm

Bien, confirmado, funciona:

He configurado como salida y a nivel alto (3,3v) el pin GPIO23 en el código así que cuando cron lance el programa se activará dicho pin a nivel alto.
Al apagar la R.Pi con cualquier comando el pin se desconfigura y deja de alimentar la base del transistor, lo cual hace que éste deje de conducir y, por tanto, el ventilador se apaga.

Hice las pruebas con un BC547 pero resulta que tiene una Intensidad de colector (Ic) de tan sólo 100mA (donde se aplican los 5v) y mi ventilador es de 290mA lo cual hace que no vaya a pleno rendimiento el ventilador y forzando dicho transistor pero me ha servido para confirmar el funcionamiento, lo he cambiado por un P2N2222A que tiene una Ic de 600mA lo cual es más que suficiente incluso para el posible pico de arranque (que no he comprobado). La resistencia (Rb) comercial usada según los cálculos ha sido de 330 ohms.

Adjunto el código final:

Code: Select all

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import commands
GPIO.setmode(GPIO.BCM)

#Salida para el Transistor que activa (High) el Ventilador y lo desactiva (Low) al apagar la R.Pi
GPIO.setup(23, GPIO.OUT)
GPIO.output(23, GPIO.HIGH)

#Salida PWM
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 1000)

#Lectura de temperatura 
def get_cpu_temp():
    tempFile = open( "/sys/class/thermal/thermal_zone0/temp" )
    cpu_temp = tempFile.read()
    tempFile.close()
    return float(cpu_temp)/1000

#Iniciar PWM
pwm.start(50)

#bucle infinito
try:
    while True:
        if get_cpu_temp() <= 40:
                pwm.ChangeDutyCycle(30)
        elif get_cpu_temp() >= 41 and get_cpu_temp() <= 50:
                pwm.ChangeDutyCycle(40)
        elif get_cpu_temp() >= 51 and get_cpu_temp() <= 60:
                pwm.ChangeDutyCycle(55)
        elif get_cpu_temp() >= 61 and get_cpu_temp() <= 70:
                pwm.ChangeDutyCycle(75)
        elif get_cpu_temp() >= 71 and get_cpu_temp() <= 80:
                pwm.ChangeDutyCycle(85)
        elif get_cpu_temp() >= 81:
                pwm.ChangeDutyCycle(100)
        time.sleep(30)

except KeyboardInterrupt:
        pwm.stop()
        GPIO.cleanup()
Aquí un sencillo esquemático que he hecho para postearlo:
Image

Gracias a todos por el interés, en especial a actkk2000 por su ayuda (con el plus de que parece ser que le gusta Kavinsky) :P

Saludos.

User avatar
actkk2000
Posts: 1309
Joined: Wed Apr 02, 2014 3:22 am

Re: Código Python para control temp. de CPU con Ventilador P

Sun Aug 28, 2016 6:58 am

No hay de que, me alegro mucho que hayas encontrado la forma de hacerlo funcionar.
Si puedes edita el titulo y agrega [solucionado] al principio para que se sepa al leerlo.
PD: Zombie since 1986 ;)

Slds!
Robot +Camara +Sensores +Encoder +Servo +Matriz8x8 +Joystick:
https://www.raspberrypi.org/forums/viewtopic.php?f=76&t=130470

nimio
Posts: 21
Joined: Sun May 05, 2013 2:51 pm

Re: Código Python para control temp. de CPU con Ventilador P

Sun Aug 28, 2016 6:29 pm

Bueno, el título es tan largo que no me cabe :lol:

Pero al menos da a entender en cierta forma que es una solución.

De todas formas he añadido "[SOLUCIONADO]" al principio del primer post.

Saludos!

EMRodriguezX
Posts: 1
Joined: Wed Feb 12, 2020 9:52 pm

Re: Código Python para control temp. de CPU con Ventilador PWM

Wed Feb 12, 2020 9:55 pm

Intento retomar el tema, he visto esta placa en bangood? Serviría?
https://www.banggood.com/es/0-24V-Top-M ... rehouse=CN

Return to “Español”