====== PWM amp cooler ====== ~~META:description abstract=Fan driver for the PWM amplifier~~ Fan driver for the PWM amplifier ===== Math ===== Max ADC input voltage is 1.1V (higher means saturated). Output of TMP36 in volts is V(T) = 0.01 * T + 0.5, targeted temperature range is at least [20 .. 100]°C, that is [0.7 .. 1.5] V. Theorical response is 0% up to 50°C, from 0% to 100% between 50°C and 75°C and 100% above 75°C. Needed multiplier before ADC is at most 1.1 / 1.5 = 0.73333, R1=33k and R2=82k fits (0.731). ADC(T) = floor(1023 / 1.1) * U(T) PWM(T) = {T / 25} - 2 (min 0, max 1). OCR0A(ADC) = 255 * ({{{1.1 / 1023} * {ADC / {R2 / {R1 + R2}}} - 0.5} / {0.01 x 25}} - 2) Using OCR0A(ADC) = 49 * (ADC - 665) / 32 (fits an int 16) gives an average of 3.6% deviation from theorical response. {{:projects:pwm_amp_cooler:amp_fan_pwm_reg.ods|Calculation file}} ===== Electronics ===== {{schematic>schematic.svg}} ===== Source code ===== // CPU frequency 9.6MHz // Temperature sensor (TMP36) on ADC3 (PB3) // MosFet output on OC0A (PB0) int main(void) { int16_t t; ADMUX = 0x43; // internal reference, right adjust, ADC3 ADCSRA = 0x87; // ADC enable, prescaler to 128 (175us/conv.) TCCR0A = 0x83; // fast pwm on OC0A TCCR0B = 0x01; // prescaler to 1 => f=37.5kHz while(1) { ADCSRA |= 0x40; // start conversion while(ADCSRA & 0x40); // wait for completion t = ADC - 665; t *= 49; // approx. t /= 32; // 1.6451 if(t < 0) t = 0; // limits if(t > 255) t = 255; // OCR0A = t; } return 0; } {{tag>analog}}