【 3D 프린터 챔버 만들기 】
[ Control Board 제작 #5 : Fan Control Class 제작 ]
□ 필요사항
: Timer1을 사용하여 Pin 9 또는 Pin 10에 25KHz PWM 출력
: RPM은 인터럽트를 사용하지 않고, 주기적으로 RPM Reading Pin 상태를 감시하여 계산
[ FanControl.h ]
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 | #ifndef FANCONTROL_H #define FANCONTROL_H #if defined(ARDUINO) && (ARDUINO >= 100) #include "Arduino.h" #else #include "WProgram.h" #endif #include <inttypes.h> class FANControl { private: class FANControl *next; static FANControl* first; unsigned long m_nMilsCheck; static int m_nPinControl; static bool m_bFansOn; int m_nPinReadRPM; int m_nPinWriteRPM; int m_nPinValue; int m_nRPM; public: FANControl(); static void InitFanTimer(); void Attach(int pinWrite, int pinRead); void Detach(); int ReadRPM(); bool IsAttached(); static void Refresh(); void SetSpeed(int speed); void FanOn(); void FanOff(); }; #endif | cs |
[ FanControl.cpp ]
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | #include "FanControl.h" ////////////////////////////////////////////////////////////// // Fans setup, PWM fans needs 25kHz PWM control (21~28kHz) // ex) 75Hz : 75/2*60 = 2,250rpm ////////////////////////////////////////////////////////////// // rpm rps sec msec // 100 1.667 0.600 600 // 200 3.333 0.300 300 // 300 5.000 0.200 200 // 400 6.667 0.150 150 // 500 8.333 0.120 120 // 600 10.000 0.100 100 // 700 11.667 0.086 86 // 800 13.333 0.075 75 // 900 15.000 0.067 67 // 1,000 16.667 0.060 60 // 1,100 18.333 0.055 55 // 1,200 20.000 0.050 50 // 1,300 21.667 0.046 46 // 1,400 23.333 0.043 43 // 1,500 25.000 0.040 40 // 1,600 26.667 0.038 38 // 1,700 28.333 0.035 35 // 1,800 30.000 0.033 33 // 1,900 31.667 0.032 32 // 2,000 33.333 0.030 30 // 2,100 35.000 0.029 29 // 2,200 36.667 0.027 27 // 2,300 38.333 0.026 26 // 2,400 40.000 0.025 25 #define FAN_FREQ 25000; // PWM fans needs 25kHz PWM control FANControl *FANControl::first; int FANControl::m_nPinControl; bool FANControl::m_bFansOn = false; FANControl::FANControl() { next = 0; m_nMilsCheck = 0; m_nPinReadRPM = 0; m_nPinWriteRPM = 0; m_nPinValue = 0; m_nRPM = 0; } void FANControl::InitFanTimer() { TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1A = _BV(COM1A1) // non-inverted PWM on ch. A | _BV(COM1B1) // same on ch. B | _BV(WGM11); // mode 10: ph. correct PWM, TOP = ICR1 TCCR1B = _BV(WGM13) // ditto | _BV(CS11); // prescaler = 8 ICR1 = 40; } void FANControl::Attach(int pinWrite, int pinRead) { next = first; first = this; m_nPinReadRPM = pinRead; pinMode(pinRead,INPUT_PULLUP); m_nPinValue = digitalRead(pinRead); m_nPinWriteRPM = pinWrite; pinMode(m_nPinWriteRPM, OUTPUT); } void FANControl::Detach() { for ( FANControl **p = &first; *p != 0; p = &((*p)->next) ) { if ( *p == this) { *p = this->next; this->next = 0; digitalWrite(this->m_nPinWriteRPM, LOW); return; } } } bool FANControl::IsAttached() { for ( FANControl *p = first; p != 0; p = p->next ) { if ( p == this) return true; } return false; } int FANControl::ReadRPM() { return m_nRPM; } void FANControl::SetSpeed(int speed) { analogWrite(m_nPinWriteRPM, map(speed, 0, 100, 0, 40)); } void FANControl::FanOn() { SetSpeed(100); } void FANControl::FanOff() { SetSpeed(0); } void FANControl::Refresh() { FANControl *p; uint8_t value; unsigned long m = millis(); unsigned long diff; for(p=first; p!=0; p=p->next) { value = digitalRead(p->m_nPinReadRPM); if(p->m_nPinValue != value) { p->m_nPinValue = value; diff = m - p->m_nMilsCheck; p->m_nRPM = (uint16_t)(15000/diff); // Convert to half signal duration to rpm : 0.5 * 0.5 * 1000 msec * 60sec / duration(msec) p->m_nMilsCheck = m; } else { if((m - p->m_nMilsCheck)>400) p->m_nRPM = 0; } } } | cs |
EOL