viernes, 28 de septiembre de 2018

REGULAR VELOCIDAD VENTILADOR SEGUN TEMPERATURA PLAYSTATION 3


Esta entrada esta basada en el trabajo de David Losada:

http://miqueridopinwino.blogspot.com/2016/08/diy-evita-problemas-de-calentamiento-PS3.html

David Losada, al que debo el post, ha ideado esta fantástica solución, mediante un sencillo chip de poco mas de 2 euros y programación se consiga regular el ventilador de las PS3 o cualquiera que este controlado por pulsos (PWM)

Al principio las videoconsolas no contaban con procesadores que generasen excesivo calor, por lo que muy pocas llevaban ventiladores, con la aparición de la PS2 y de la XBOX se cambio el diseño, era necesario evacuar el calor que generaban los procesadores, y para ello se dotaron de amplios disipadores con ventiladores...

Las consolas están destinadas a ser un centro de juegos y generalmente se ponen en la sala de estar, cuando salieron las primeras PS3 muchos usuarios se quejaron del alto ruido que generaban al calentarse...Sony cambio el diseño y saco los modelos slim y superslim..

En las primeras PS3 la alta temperatura dañaba las soldaduras del procesador (soldaduras que de fabrica tampoco eran las mejores), el resto de PS3 sufren tambien de calentamientos que al cabo de pocos años pasa factura.

Como otros periféricos como los PCs, la PS3 tiene tambien un ventilador regulado por pulsos PWM,


Hay gente que ha regulado el ventilador de forma fija para que vaya siempre más acelerado (con una resistencia en el cable gris conectado a los 12V, regulando a 1V aprox., o bien con un potenciómetro para hacerlo manualmente), pero no es la mejor solución ya que no tiene en cuenta la temperatura del procesador (que puede variar mucho según la temperatura ambiente), y aunque funciona, al tener que cubrir todos los casos, suele quedar más ruidoso.


Para este mod se va a usar el chip attiny85 de Atmel. Es un chip se puede programar fácilmente con Arduino.


Materiales
1. Módulo Attiny85 Digispark Digispark (placa derivada de Arduino, con conexión USB). Esta placa es pequeña, económica y compatible con el IDE ARDUINO. Por su dimensiones es perfecta para desarrollos que requieran poco espacio, cuenta con 6 pines I/O, dos de los cuales son utilizados durante la carga por USB. 
  • Alimentación externa 5v­12v 
  • Corriente máxima 500 mA 
  • Comunicación USB, I2C(UART Sof.) 
  • PWM 3 Canales ADC 4 
  • Canales Memoria 8K (2 para bootloader ) 
  • Recomendaciones: Usar alimentación externa inferior a 12V.






2. sensor de temperatura para regular la línea PWM (cable gris) del ventilador de la PS3 slim entre 0,8V y 1,3V

En la siguiente foto vemos los cables ya soldados. 


En el pin 4 tenemos la regulación PWM (cable amarillo), en el 2 un lado del sensor (por el otro lado la resistencia que necesita a masa) y el otro lado del sensor a 5V out del chip. 


Y la alimentación conectada directamente a la alimentación del ventilador (el regulador integrado admite entre 6 y 15V).

Se ha soldado directamente la resistencia 6K8 que necesita este sensor NTC  por la parte de atrás de esta pequeña placa:.

Una vez programado (el programa Arduino esta al final de este tutorial), se procede a instalarlo.

Una vez que la tengamos la PS3 sin la carcasa superior, podremos ver los tres cables que van de la placa al ventilador. El rojo es el positivo +12V, el negro es masa o -12V y el gris es el de regulación de voltaje por anchura de pulsos.



Cortamos el gris, aislando el trozo que viene desde la placa base con un poco de cinta aislante para evitar que toque cualquier parte y se produzca un indeseado corto. La parte que nos interesa es la que sale del ventilador, y es sobre la que vamos a regular el ventilador. 


Para conectar los cables rojo y negro sólo los he pelado un poco sin llegar a cortarlos, para aplicarles un poco de estaño con el soldador y alimentar con ellos el ATTINY85.

ES MUY IMPORTANTE colocar bien el sensor de temperatura, para que haga buen contacto con el disipador del RSX, de ello depende que se regule correctamente. Yo lo he sujetado con silicona (puede aguantar temperaturas altas) una vez que he comprobado que todo funcionaba bien: 


Se escamotean bien los cables y se cierra la consola de nuevo.

PROGRAMA

Instrucciones de instalación del software: http://digistump.com/wiki/digix/tutorials/software

El Digispark funciona igual al resto de productos Arduino, excepto que durante la carga del software no hay que conectar el Digispark al inicio. Hay que pulsar antes el botón de subida y en el cuadro inferior de estado se pedirá que conectemos el Digispark, en ese momento se debe enchufar o desconectar y conectar nuevamente. Empezará el progreso de carga y cuando termine ejecutará inmediatamente el código introducido en el Digispark.

Al conectarlo siempre espera 5 segundos antes de que el código se ejecute. Este retardo es la comprobación para determinar si se está tratando de programar.
/*  ==================================================================

  Sketch control ventilador por PWM con ATTiny85 económico termistor NTC.
  Configurado para ventilador Playstation 3; con autolimpieza al arranque.
  
  Autor: David Losada, basado en trabajos de Rafael Torrales y Antonio Moles.
  Version: 1.32 (Ahora la autolimpieza la hace cada vez que se enciende la consola)
  Fecha: 20 de julio de 2016. Última actualización 7/02/2017
  Compila con Arduino 1.6.9

    ==================================================================   */

#include  //Instalar esta rutina si no la tenéis; está en el repositorio general de Arduino 1.6.9
//Si anduviéramos cortos de memoria, habría que eliminar la librería EEPROM y el código relacionado

//******************* A CAMBIAR SEGÚN TU CONFIGURACIÓN ********************************
//Control temperatura
const float resistor = 6800; //El valor en ohmnios de la resistencia del termistor a 25ºC
const float voltage = 5.0; // El voltaje real en el punto 5Vcc de tu placa Arduino

//Deltas de temperatura
int tempMin = 20; //Temperatura mínima de activación del ventilador
int tempMax = 37; //temperatura a la que funcionará al 100%
//0,85V=velocidad mínima de vent. PS3 y 1,25V vel. máxima
float PWMMin = 0.65; //Voltaje PWM de funcionamiento con temp. mínima (el de la PS3 se pone en marcha con 0,8V)
float PWMMax = 1.3; //Voltaje PWM de funcionamiento al máximo ventilador
//Hay que tener en cuenta que los voltajes se ajustan a las temperaturas pero no se ciñen a ellas,
//es decir, que a tempMin el voltaje será PWMMin, pero a menor temp. el voltaje bajará, y lo mismo
//con el voltaje máximo; si sigue subiendo la temperatura, el voltaje PWM aumentará en consecuencia,
//hay que tener cuidado porque podríamos dar más voltaje del necesario al ventilador

//Definición pines digitales para activar relés
int TempPIN=1; //En el ATTiny85 las entradas son (1)=P2; (2)=P4; (3)=P3; (0)=P5 -> Pin al que conectamos el termistor
int motorPWM=4; //Pin PWM de control motor; P0, P1, P4 el en ATTiny85
const int frecseg = 1; //Tiempo en segundos entre cada ejecución del programa (recomendado entre 1 y 5 segundos)
int ledPIN=1; //Según la placa, en este caso el LED del ATTiny85 B es el 1

//Variables
float Temp= 0; //Valor entrada sensor temp
int fanSpeed= 0; //Velocidad de motor
long timeLED=0; //Para almacenar tiempo
unsigned long millisInicio=0; //Para comprobar paso de horas

//Parte del cálculo temperatura
//Para ahorrar cálculos lo definimos como constante en esta parte del programa
const float K= 273.15; //Para pasar a grados Kelvin
const float e = 2.718281828459045; //Constante matemática 
//const float B = log(RPto2/RPto1)/(1/(TPto2+K)-(1/(TPto1+K))); //Valor Beta de tu termistor calculado de dos puntos
const float B = 3850; //Valor Beta del Datasheet; comentar esta línea si se meten los datos de los dos puntos
const float unodivr = 1/(resistor * pow(e,(-B/298.15))); //Con pow elevamos e al resultado

float T = 0; //Declaramos la variable Temperatura
int grados, decimas; //Para ponerle coma al resultado (en español)

void setup()   { 
//Resetea la EEPROM la primera vez que la usamos
EEPROM.setMemPool(0,512); //Establecemos inicio y tamaño de EEPROM de la tarjeta utilizada
EEPROM.setMaxAllowedWrites(128); //Mínimo para que pueda hacerse el primer borrado completo
//rellenamos de 0 los datos de EEPROM
//Attiny85 tiene 512 Bytes de EEPROM; ajustar según el que uséis
if (EEPROM.readLong(508)!=7091976) { //En ese punto, preferiblemente al final, guardo un valor para saber si ya la he reseteado
  for(int i=0; i<502 -="" 0="" 10000="" 10="" 16="" 1:="" 255="" 25ms="" 2:="" 2="" 3:="" 3="" 5="" 5v="" :="" a="" acar="" acemos="" activaci="" actuamos="" al="" alimentar="" alor="" anal="" analogwrite="" and="" ara="" arte="" attiny85="5V" attiny="" aumente="" ax="" b="(RPto2/RPto1);//(1/(TPto2+K)-(1/(TPto1+K)));" bajar="" basandose="" beta.="" calcula="" calcular="" caracteres="" coja="" comprobando="" con="" consecuencia="" consola="" convertimos="" correcta="" corresponde="" de="" dejamos="" del="" delay="" desde="" disponible="" divisor="" ecesitamos="" ecoge="" ecuaci="" eeprom.update="" eeprom="" efinir="" egla="" el="" elocidad:="" emp:="" emp="" emppin="" en="" encendido:="" enciende="" entre="" erial.print="" erial.println="" espera="" estar="" fanspeed="" filas="" final="" float="" for="" forma="" gico="" ha="" haga="" i="" iempo="" if="" in="" indicativo="" inicializado="" input="" int="" justar="" la="" lcd.begin="" lecturas="" led="" ledpin="" leemos="" limpieza="" lmacenamos="" lo="" loop="" los="" ltima="" m="" media="" mediante="" medias="" mero="" millisinicio="millis();" modifica="" motor="" motorpwm="" n="" no="" o="" omprobamos="" onemos="" onvertimos="" orrado="" output="" pantalla="" para="" parar="" parpadear="" parte="" pines="" pinmode="" ponemos="" por="" posici="" progresiva="" puerto="" pwm="" pwmmax="(255*PWMMax)/5;" pwmmin="(255*PWMMin)/5;" que="" r1="r1a" r1a="(voltage*float(resistor))/v2;" rango="" resistance="" resistencia="" resistor="" revoluciones="" sacar="" se="" seg="" segundos="" serial="" so="" sobre="" speramos="" steinhart-hart="" t="B/log(r1*unodivr);" tama="" tarda="" temp="" temperatura="" tempmax="" tempmin="" tenemos="" terminado="" thermistor="" tiempo="" timeled="" tope="" total="" tres="" un="" v2="(R2*V)/(R1+R2)" valor="" valores="" veces="" velocidad="" ventilador="" void="" voltage="4.83" voltaje="" voltios.="" voltios="" voltmax="" volvemos="" x="" ximas="" y="" ya="">millis()) { //Cuando pasen 50 dias resetear
    timeLED=millis();
  }
  if ((millis()-timeLED)>frecseg*1000*2) {
      analogWrite(ledPIN,100); //enciende LED indicando funcionamiento
      timeLED=millis();
  }
    if ((millis()-timeLED)>frecseg*1000) {
      analogWrite(ledPIN,0); //apaga led
    }

//Si ha pasado una hora desde la puesta en marcha, añadimos una hora
// al contador de la EEPROM, para estadística
if ((millis()-millisInicio)>3600000) { //Ha pasado una hora
  millisInicio=millis(); 
  EEPROM.update(0,EEPROM.readLong(0)+1); //Añadimos una hora
}

  delay(frecseg*1000); //Ponemos en espera al Atmel
}

// *************** RUTINA MAP MEJORADA (admite fracciones)
double doubleMap(double x, double in_min, double in_max, double out_min, double out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
  

<255 br="" i="i+25)"><5 br="" nbsp="" x=""><--final br="">




No hay comentarios: