PWMファンコントローラーの製作

最終更新時間:2021年05月29日 11時25分05秒

[公開:any]

[電子工作/一般]
[電子工作/PIC]
[PIC12F683,PWM]

origin 2021-05-29


 気温が高くなるとアマチュア無線で使用する電源や無線機が熱くなるため、筐体を冷やす冷却ファンが欲しくなります。ハードディスクの平面用冷却ファンが手持ちであったのでこれを使用してみたのですが、ファンの回転数が高いので耳障りな音がします。回転数を制御するには電源電圧でも可能ですが、PICを使ってPWM制御することにします。

PICのPWMでファンコントロール

 PICは買い置きのあったPIC12F683を使用します。以前は同じPICで温度センサーLM35DZを使用したファンコントローラーを作りましたが、温度制御までは不要なのでボリュームで回転数を制御する方式とします。PICの出力するPWMでMOS-FETの2SK2231をON/OFFさせてファンの回転数を制御します。MOS-FETは使用するファンの定格を扱えるものが必要です。このファンの電流値は、最大となるスタートアップ時で300mA程度なので、この電流が扱えるMOS-FETならOKです。2SK2231は完全にオーバースペックとなりますが、大きなファンも利用する可能性があるのでこのままとします。電源電圧は使用するファンに合わせることができますが、使用する3端子レギュレーターの最低必要電圧以上でMOS-FETの対応電圧以下となります。

ファンコントローラー回路図

 簡単な回路ですが、久しぶりにPCBEで実装パターンを描いてみました。ユニバーサル基板に実装する場合は、こうやってパターンを決めておくと失敗が少なくなります。基板は秋月電子オリジナルのメッシュ基板です。別にメッシュである必要はないのですが、手持ちで一番小さな基板なので使用しました。

ファンコントローラー回路図

 基板に部品を実装してケースに入れました。ケースも秋月電子のプラケース(小)です。ファンを電源の上にセットしてサイドをスポンジで密着させます。これで効率よく天板の放熱板を冷却することができます。

PIC-PWMファンコントローラー

 PICのプログラムはMPLABとXC8で作成しました。処理はとても簡単でADCでボリューム値を読み取って、その値からPWM値をセットするだけです。PWMの周波数は16KHzです。ファンによってはこの周波数で滑らかに回らないものがあるかもしれませんが、これよりも周波数を下げると可聴音となるため耳障りな音が聞こえます(若い方は16KHzでも聞こえるかもしれない)。ADCは10ビットで結果が得られますが、PWMは周波数によっては10ビットの制御ができない場合があります。この計算方法は、詳しく解説したWebサイトがたくさんあるのでそちらを参考にしてください。今回もフルビットの制御ができないので適当にADC値を除算してボリュームの最小最大でいい感じになるようにしてあります。ボリュームで回転数を落とした状態でファンをスタートさせると回らないことがあるので、電源投入時は2秒間だけ全開で回してその後、設定した回転数になるようにしています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * File:   pwm_fan_controler
 * Author: www.henteko.org
 *
 * Created on 2021/05/23, 11:48
 */

#include <xc.h>

#pragma config FOSC = INTOSCIO
#pragma config WDTE = OFF
#pragma config FCMEN = OFF
#pragma config PWRTE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config MCLRE = OFF

#define _XTAL_FREQ  8000000 

void delay_ms(unsigned int t) {
    for(; t > 0; t--)
        __delay_ms(1);
}

unsigned int get_adc(unsigned char ch) {
    ADCON0bits.ADFM = 1;        // padding right
    ADCON0bits.VCFG = 0;        // VREF=VDD
    ADCON0bits.CHS = ch;        // ADC channel
    ADCON0bits.GO_nDONE = 0;    // ADC GO/^DONE
    ADCON0bits.ADON = 1;        // ADC Enable
    __delay_us(25);
    GO = 1;
    while(GO);
    return (ADRESH << 8) + ADRESL;
}

void set_duty(unsigned int duty) {
    CCPR1L = duty >> 2;
    CCP1CONbits.DC1B = duty & 0b00000011;
}

void main(void) {
    unsigned int duty;
    
    OSCCON = 0b1110000;    // clock 8MHz
    
    ANSEL = 0b1011000;    // ADC Fosc/16. AN3 analog
    CMCON0 = 0b00000111;    // comparator off
    TRISIO = 0b00010000;    // GP4 input  

    CCP1CON= 0b00001100;    // PWM mode
    T2CONbits.T2CKPS = 00;    // prescaler 1/1 8000000/4=0.5us
    PR2 = 124;            // PWM frequency 0.5us * (124 + 1) = 62.5us = 16kHz
    TMR2 = 0;            // tmr2 count
    T2CONbits.TMR2ON = 1;    // tmr2 on

    set_duty(1023);
    delay_ms(2000);
    
    while(1) {
        duty = get_adc(3);
        set_duty(duty / 2);
    }
}

このテンプレートをデザインした者がへたれなので IE6 には非対応です。IE7FirefoxSafariOperaChrome など、モダンなブラウザを利用して下さい。


▲ページ Top へ...