Browse Source

first commit, functinal attiny code

master
Barb 11 months ago
commit
882f751219
2 changed files with 88 additions and 0 deletions
  1. +77
    -0
      25KHz_PWM_Tiny.ino
  2. +11
    -0
      README.md

+ 77
- 0
25KHz_PWM_Tiny.ino View File

@ -0,0 +1,77 @@
// normal delay() won't work anymore because we are changing Timer1 behavior
// Adds delay_ms and delay_us functions
#include <util/delay.h>
// Clock at 8MHz
#define F_CPU 8000000 // This is used by delay.h library
word VentPin = 1;
word DetPin = A0;
float PWM = 50; // takes values from 0 to 100
float PWM9, PWM8, PWM7, PWM6, PWM5, PWM4, PWM3, PWM2, PWM1;
// Thermistor
int Vo;
int DeltaT = 10; // shift curve up/down
float R1 = 13000;
float logR2, R2, T;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
// Boot up delay countdown to keep the fan spinning initially
int countdown = 10000; //Microseconds to delay
void setup() {
//Serial.begin(115200);
TCCR0A = _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
TCCR0B = _BV(WGM02) | _BV(CS01);
// Set TOP and initialize duty cycle to zero(0)
OCR0A = 40; // TOP - DO NOT CHANGE, SETS PWM PULSE RATE
OCR0B = 30; // duty cycle for Pin 1(PB1) - generates 1 500nS pulse even when 0
pinMode(VentPin, OUTPUT);
pinMode(DetPin, INPUT);
}
void loop() {
// Thermistor data acquisition
Vo = analogRead(DetPin);
R2 = R1 * (1023.0 / (float)Vo - 1.00);
logR2 = log(R2);
T = (1.00 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
T = T - 273.15;
// End of temperature measurement
// PWM control Logic
if (T < 30) {
// this next if is necessary to trick BIOS into thinking it xontrols the fan at boot
if (countdown > 0) {
countdown--;
delayMicroseconds(100);
PWM = 50;
}
else if (T < 15 && countdown <= 0) {
PWM = 0; // stop the fan if the machine is critically cold
}
else {
PWM = 25; // minimum fan speed while operating normally
}
}
else if (T >= 30+DeltaT && T < 40+DeltaT) {
PWM = 2*T - (35+2*DeltaT); // first part of the fan curve
}
else if (T >= 40+DeltaT) {
PWM = 5*T - (155+5*DeltaT); // second, steepest, part of the curve
}
// these variables are used to average the value over 10 cycles before sending it to the fan
PWM9 = PWM8,
PWM8 = PWM7;
PWM7 = PWM6;
PWM6 = PWM5;
PWM5 = PWM4;
PWM4 = PWM3;
PWM3 = PWM2;
PWM2 = PWM1;
PWM1 = PWM;
OCR0B = (PWM9+PWM8+PWM7+PWM6+PWM5+PWM4+PWM3+PWM2+PWM1+PWM)/30; // average and send value to timer
}

+ 11
- 0
README.md View File

@ -0,0 +1,11 @@
DIY fan controller for ThinkPads (should be adaptable to other laptops/desktops).
Introduction/Rationale:
Newer ThinkPads are dumb, their fan controllers use an obscure method of communication with the kernel, that does not give direct access to PWM frequency. The fan(s) is(are) either off, or on in one of 2 or 3 levels, making for very jarring transitions that are clearly audible.
This project aims to replace the built-in PWM controller with an attiny or other arduino compatible board containing a custom fan curve. The controller reads a temperature value from a thermocouple and sets the fan accordingly, proportionally to the given temperature.
Future goals:
- add serial/usb communication
- add buttons/switch to choose between fan curves
- add software control mode (with fallback to default built-in curve when serial is down)

Loading…
Cancel
Save