02 October, 2016

DIY: Avoid overheating problems on your PS3 with a chip and sensor for 5 bucks


With a small chip Digispark ATtiny85 will see how to regulate the fan of the PS3 (or any PWM-controlled fan) depending on temperature, avoiding wear and tear prematurely. 
Engineers PS3 gave priority to the silence of the PS3 , since it is intended to be a center of games and multimedia, so the processors can reach damaging temperatures for the welds thereof, and within a few years ends up breaking down by poor contact welding (reparable only with reflow or reballing).
The PS3 has a pulse PWM controlled fan, Atmel ATtiny85 and can be easily programmed with the Arduino IDE.
There are examples on Youtube and internet people that has regulated the fan fixedlyto go ever faster (with a resistance in the gray wire connected to the 12V, regulating 1V approx., Or with a potentiometer to do it manually) but is not the best solution because it does not consider the processor temperature (which can vary greatly depending on ambient temperature), and although it works, having to cover all cases, there isusually noisier.  and with this solution we have the advantage that if we hear the very loud fan, you will surely have a problem of lack of ventilation dust or other problem.

materials


We just need the ATtiny85 ( very useful for small and simple projects as we saw in the previous tute , with 8 Ks capacity ) taking into account their differences:
  1. The Digispark works with an  Atmel ATtiny85 MCU  - has some differences from the ATmega328 and some libraries do not work properly, but will improve over time.
  2. The Digispark only 6 KB of memory  available for our code (8 KB if we remove the virtual USB bootloader and  we programmed directly with an Arduino UNO ).
  3. Pin 3 and Pin 4 (P3 and P4) are used for communications and USB programming ; if only it interferes if we use the USB connection and can be used while not use the USB connection on the final design, but keep in mind that if the program acts dramatically on the voltage thereof, will be best to disconnect once we uploaded the program by USB.
  4. Pin 3 (P3) is connected to a pull-up resistor 1.5 KQ  required when P3 and P4 are used for USB communication (programming included). Your design will have to take that into account and you'd have to supercharge the pin to put it in LOW.
  5. The Digispark  does not have a serial port hardware  or a converter to USB. A library of example (DigiUSB) as well as some sample code and a monitor program series, but communication with the computer will not always plug and play, especially when there are other libraries in use is provided.
  6. On power does nothing until 4 seconds later , as it is the waiting time that is scheduled for programming USB (this I think can be eliminated by programming directly , but I have not tried), so must be taken into account if we need quick start the program.
  7. While digital connections correspond to the pins (digitalRead (0) where 0 = Pin0),  the correspondence of the analog pins change :
analogRead (1); // Read P2
analogRead (2); // Read P4
analogRead (3); // Read P3
analogRead (0); // Read P5

A we add a temperature sensor to regulate the PWM line (gray wire) Fan PS3 slim between 0.8V and 1.3V and less than 5 € we regulator.
In the next picture we see the cables and soldiers. 
  • On pin 4 we have the PWM control, 
  • 2 in one side of the sensor (on the other hand the resistance needs mass) and the other side of the sensor chip to 5V out.
  • And the power supply connected directly to the fan (integrated controller supports between 6 and 15V).



I soldered directly 6K8 resistance you need this sensor NTC (such as those used in the previous tute for more info) on the back of this small plate:



Once programmed (Arduino at the end of this step by step program), we proceed to install. I will not go into the details of how to disarm; Internet is full of tutorials about it.

Once we have uncovered, we can see the three wires going to sink. Red is the positive + 12V, black is mass or -12V and gray is the voltage regulation pulse width ( PWM Wikipedia ).
We cut the gray, isolating the piece that comes from the motherboard with some duct tape to prevent touch anywhere and a short unwanted occurs. The part that interests us is coming out of the fan , and on which we regulate the fan.


To connect the red and black wires only I peeled a bit without being cut, to apply some solder with the soldering iron and feed them the ATtiny85.


IT IS VERY IMPORTANT well placed temperature sensor, to make good contact with the heatsink RSX, it depends which is adjusted correctly. I have attached silicone (can withstand high temperatures) once you've checked that everything worked well:


And it has already been us with the source placed on your site.


I have several chips ready programmed with the sensor and ready to install; if anyone is interested to contact me to do her a favor and send it by mail.

In the following video you can see all the steps and the difference of the original fan RPM and with our automatic controller:


The program is as follows ; I added code to do self - cleaning every 25 hours (configurable) activating the fan to stop for 3 seconds:

 /* ==================================================================  
   
  Sketch control ventilador por PWM con ATTiny85 económico termistor NTC.  
  Configurado para ventilador Playstation 3; con autolimpieza cada x horas.  
    
  Autor: David Losada, basado en trabajos de Rafael Torrales y Antonio Moles.  
  Version: 1.0  
  Fecha: 20 de julio de 2016  
   
   
   ==================================================================  */  
   
 //#include  //He utilizado primero un MEGA 2560 con pantalla LCD Keypad Shield para probar el código antes de pasarlo  
 #include  //Si anduviéramos cortos de memoria, habría que eliminar la librería EEPROM y el código relacionado  
 // select the pins used on the LCD panel  
 //LiquidCrystal lcd(8, 9, 4, 5, 6, 7);  
   
 //******************* 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; ajustar a los valores que os vayan mejor con la colocación del sensor
 int tempMin = 20; //Temperatura mínima de activación del ventilador  
 int tempMax = 37; //temperatura a la que funcionará al 100% (teniendo en cuenta el contacto del sensor)
 //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 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  
 int hrsLimpieza=25; //0=Desactivado; configura aquí cada cuántas horas quieres que se limpie al activar a tope el ventilador por 5 segundos  
   
 //Variables  
 float Temp= 0; //Valor entrada sensor temp  
 int fanSpeed= 0; //Velocidad de motor  
 long timeLED=0; //Para almacenar tiempo  
 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 (EEPROMReadlong(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="" 16="" 1:="" 255="" 25ms="" 2:="" 2="" 3:="" 5="" 5v="" :="" a="" acar="" acemos="" activaci="" actuamos="" al="" alor="" anal="" analogwrite="" and="" arte="" attiny85="5V" attiny="" aumente="" ax="" b="(RPto2/RPto1);//(1/(TPto2+K)-(1/(TPto1+K)));" bajar="" basandose="" beta.="" calcula="" calcular="" caracteres="" comprobando="" con="" consecuencia="" convertimos="" correcta="" corresponde="" de="" del="" delay="" desde="" disponible="" divisor="" ecesitamos="" ecoge="" ecuaci="" eeprom="" eepromwritelong="" efinir="" egla="" el="" elocidad:="" emp:="" emp="" emppin="" en="" encendido:="" entre="" erial.print="" erial.println="" espera="" estar="" fanspeed="" filas="" final="" float="" for="" gico="" ha="" haga="" i="" iempo="" if="" in="" indicativo="" inicializado="" input="" int="" justar="" la="" lcd.begin="" lecturas="" led="" ledpin="" leemos="" lmacenamos="" lo="" loop="" los="" ltima="" media="" mediante="" medias="" mero="" millisinicio="millis();" modifica="" motor="" motorpwm="" n="" no="" o="" omprobamos="" onvertimos="" orrado="" output="" pantalla="" para="" parpadear="" parte="" pines="" pinmode="" por="" posici="" puerto="" pwm="" pwmmax="(255*PWMMax)/5;" pwmmin="(255*PWMMin)/5;" que="" r1="r1a" r1a="(voltage*float(resistor))/v2;" rango="" resistance="" resistencia="" resistor="" sacar="" se="" seg="" serial="" so="" sobre="" steinhart-hart="" t="B/log(r1*unodivr);" tama="" temp="" temperatura="" tempmax="" tempmin="" tenemos="" terminado="" thermistor="" tiempo="" timeled="" tres="" un="" v2="(R2*V)/(R1+R2)" valor="" valores="" veces="" velocidad="" void="" voltage="4.83" voltaje="" voltios.="" voltios="" voltmax="" x="" y="" ya="">millis()) { //Cuando pasen 50 dias resetear  
   timeLED=millis();  
  }  
  if ((millis()-timeLED)>frecseg*1000*2) {  
    analogWrite(ledPIN,100); //enciende LED indicando funcioanmiento  
    timeLED=millis();  
  }  
   if ((millis()-timeLED)>frecseg*1000) {  
    analogWrite(ledPIN,0); //apaga led  
   }  
   
 //Si ha pasado una hora desde la puesta en marcha, comprobamos si >= Horas limpieza  
 //Y si es así, ponemos al tope el ventilador 3 segundos  
 if ((millis()-millisInicio)>3600000) { //Ha pasado una hora  
  millisInicio=millis();   
  EEPROMWritelong(0,EEPROMReadlong(0)+1); //Añadimos una hora  
  if (hrsLimpieza!=0 && (EEPROMReadlong(4)-EEPROMReadlong(0))>=hrsLimpieza) {  
   EEPROMWritelong(4,EEPROMReadlong(0)); //Salvamos punto de activación ventilador  
   analogWrite(motorPWM,255); //Ponemos a tope el ventilador  
   delay(3000); //Esperamos 3 segundos  
   analogWrite(motorPWM,fanSpeed); //lo volvemos a su velocidad previa  
  }  
    
 }  
   
  delay(frecseg*1000); //Ponemos en espera al Atmel  
 }  
   
 //This function will write a 4 byte (32bit) long to the eeprom at  
 //the specified address to address + 3.  
 void EEPROMWritelong(int address, long value)  
    {  
    //Decomposition from a long to 4 bytes by using bitshift.  
    //One = Most significant -> Four = Least significant byte  
    byte four = (value & 0xFF);  
    byte three = ((value >> 8) & 0xFF);  
    byte two = ((value >> 16) & 0xFF);  
    byte one = ((value >> 24) & 0xFF);  
   
    //Write the 4 bytes into the eeprom memory.  
    EEPROM.write(address, four);  
    EEPROM.write(address + 1, three);  
    EEPROM.write(address + 2, two);  
    EEPROM.write(address + 3, one);  
    }  
      
 long EEPROMReadlong(long address)  
    {  
    //Read the 4 bytes from the eeprom memory.  
    long four = EEPROM.read(address);  
    long three = EEPROM.read(address + 1);  
    long two = EEPROM.read(address + 2);  
    long one = EEPROM.read(address + 3);  
   
    //Return the recomposed long by using bitshift.  
    return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);  
    }  

In this video you can see how economic ATtiny85 program:


Another improvement: Increase cooling the power supply of the PS3

For those interested, first I had the idea to improve heat dissipation from the source by adding an aluminum plate of 1 mm. clipped and bolted to the two dissipators having, to more easily remove heat from regulators and MOSFET and last us:


I applied silicone or thermal plasta over both sinks:


Let it stick for a day at least and then drilled in every sink to put the screws to secure it well and improve contact (optional if we used silicone):


We must make room for the plastic holders, luckily 1 mm. Aluminum is easy to cut with strong scissors electrician eg .:


Thanks to this mod, our play "will play" much longer, it takes a month working and only slightly perceived the fan if you remove the sound, and its temperature has dropped at least 15 ° C of factory settings.

And that's all for now, thanks for your comments!

More information: 
https://digistump.com/wiki/digispark/tutorials/basics 
http://digistump.com/wiki/digispark/tutorials/connecting
Thermistor 6K8: 

1 comment :

  1. Project very interesting. Congratulations.

    ReplyDelete