DIY fan controller for ThinkPads (should be adaptable to other laptops/desktops).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.2 KiB

  1. // normal delay() won't work anymore because we are changing Timer1 behavior
  2. // Adds delay_ms and delay_us functions
  3. #include <util/delay.h>
  4. // Clock at 8MHz
  5. #define F_CPU 8000000 // This is used by delay.h library
  6. word VentPin = 1;
  7. word DetPin = A0;
  8. float PWM = 50; // takes values from 0 to 100
  9. float PWM9, PWM8, PWM7, PWM6, PWM5, PWM4, PWM3, PWM2, PWM1;
  10. // Thermistor
  11. int Vo;
  12. int DeltaT = 10; // shift curve up/down
  13. float R1 = 13000;
  14. float logR2, R2, T;
  15. float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
  16. // Boot up delay countdown to keep the fan spinning initially
  17. int countdown = 10000; //Microseconds to delay
  18. void setup() {
  19. //Serial.begin(115200);
  20. TCCR0A = _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
  21. TCCR0B = _BV(WGM02) | _BV(CS01);
  22. // Set TOP and initialize duty cycle to zero(0)
  23. OCR0A = 40; // TOP - DO NOT CHANGE, SETS PWM PULSE RATE
  24. OCR0B = 30; // duty cycle for Pin 1(PB1) - generates 1 500nS pulse even when 0
  25. pinMode(VentPin, OUTPUT);
  26. pinMode(DetPin, INPUT);
  27. }
  28. void loop() {
  29. // Thermistor data acquisition
  30. Vo = analogRead(DetPin);
  31. R2 = R1 * (1023.0 / (float)Vo - 1.00);
  32. logR2 = log(R2);
  33. T = (1.00 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
  34. T = T - 273.15;
  35. // End of temperature measurement
  36. // PWM control Logic
  37. if (T < 30) {
  38. // this next if is necessary to trick BIOS into thinking it xontrols the fan at boot
  39. if (countdown > 0) {
  40. countdown--;
  41. delayMicroseconds(100);
  42. PWM = 50;
  43. }
  44. else if (T < 15 && countdown <= 0) {
  45. PWM = 0; // stop the fan if the machine is critically cold
  46. }
  47. else {
  48. PWM = 25; // minimum fan speed while operating normally
  49. }
  50. }
  51. else if (T >= 30+DeltaT && T < 40+DeltaT) {
  52. PWM = 2*T - (35+2*DeltaT); // first part of the fan curve
  53. }
  54. else if (T >= 40+DeltaT) {
  55. PWM = 5*T - (155+5*DeltaT); // second, steepest, part of the curve
  56. }
  57. // these variables are used to average the value over 10 cycles before sending it to the fan
  58. PWM9 = PWM8,
  59. PWM8 = PWM7;
  60. PWM7 = PWM6;
  61. PWM6 = PWM5;
  62. PWM5 = PWM4;
  63. PWM4 = PWM3;
  64. PWM3 = PWM2;
  65. PWM2 = PWM1;
  66. PWM1 = PWM;
  67. OCR0B = (PWM9+PWM8+PWM7+PWM6+PWM5+PWM4+PWM3+PWM2+PWM1+PWM)/30; // average and send value to timer
  68. }