====== 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}}