4 pinli (bilgisayar) fan kontrolü

Sercan

--
Katılım
17 Mart 2019
Mesajlar
4,927
Elimde bir çok fan var. Bunlar genellikle 3 pinli. 3 pinli fanlar Vcc, GND ve Tach (Takometre, devir saat çıkışı) bağlantılarından oluşur.

20230512_222958.jpg



Bugün ise elime 4 pinli fan geçti. Bu fan türü genellikle bilgisayar işlemcisi için kullanılır. 4. pin PWM ile fanın kontrolünü mümkün kılar.

20230513_014437.jpg



Renkler zaman zaman değişse sıralamada genel mantık aşağıdaki şekildedir. GND her zaman siyah renklidir.

1. pin GND
2. pin Vcc - (PC için genellikle 12VDC)
3. pin Tach - (takometre, devire saat çıkışı)
4. pin PWM - (Pulse Width Modulation, Sinyal Genişlik Modülasyonu)

Benim durumda bağlantıların renkleri aşağıdaki şekilde;
Mavi Tach, Sarı ise PWM pini

1683931340311.png


Öncelikle devir saatinin hesaplaması ile bazı bilgilere değinmek gerekiyor.

Bu pin Hall-effect sensörün çıkışı olduğunu unutmamak lazım. Bu pinin pull-up direnci ile 3.3V DC ya da 5V DC ye bağlanması rekebildiğini de unutmayın ki benim fan da bu gerekti. Burada dikkat edilmesi gereken önemli bir konu var. Fan 12V DC ile çalışıyor ancak Tach pini 5V ya da 3.3V DC ile çalışıyor. 5V üzerindeki voltajlara çok hassas olabiliyor. Sizdeki fanın özelliklerini iyi incelmenizi tavsiye ederim.

Devir saati çıkış sinyali Hertz (= saniye başına) cinsinden iken, fan hızlarının genellikle RPM (= devir/dakika) cinsinden belirtildiğine de dikkat edin. Bu, sinyalin RPM'ye dönüştürülmesi için 60 ile çarpılması gerektiği anlamına gelir. Ancak, bendeki fan devir başına iki impuls verdiğinden, okunan değer de 2'ye bölüyorum.

Sonuç olarak, benim için doğru RPM hızını elde etmenin formülü şöyledir:

fan hızı [rpm] = frekans [Hz] × 60 ÷ 2

ScreenImg(2).png


Yukarıdaki dalga formu (bendeki fanın en yüksek hızı) için hesaplama aşağıdaki gibi oluyor:

115 [Hz] ÷ 2 × 60 = 3450 [rpm]


PWM sinyaline gelecek olursak, durağan halden ilk hareket verildiğinde bu sinyalin %20-%25 civarında olması gerektiği yazıyor. Bunun dışında özel bir bilgi görmedim. Arduino PWM çıkışı ile doğrudan sürdüm.


Sonuç olarak, fanı daha önce aşağıdaki konuda kullandığım Arduino koduna entegre ettim. Bu sayede uzaktan kumanda ile PWM çıkışını değiştirip, dolayısıyla fan hızını kumanda ile kontrol edip, devir saatini osiloskop ile inceledim.


Fan hızının değişimini benim gördüğüm kadar belirgin ifade etmiyor ama genede çalışırken çektiğim videosunu paylaşayım. Sesi dikkatli dinlerseniz fan hızının değişimini daha iyi fark edebilirsiniz.




Kurduğum devrenin fan bağlantı şeması:


1683939981317.png



Tüm kod (burası TM1628 konusundaki bütün kodu da içerir):
#include <IRremote.h>
#include <TM1628.h>
int intensity = 0;
int initClockLED = 0;
int Volume = 20;
#define PWM_PIN 6
int PWM_VALUE = 51;

unsigned long lastCommandTime = millis();
int sourcesInit = 0;
unsigned char sources[] = { 0x00, 0x03, 0x0C };
int playPauseInit = 0;
unsigned char playPause[] = { 0x01, 0x02 };
int functionsInit = 0;
unsigned char functions[] = { 0x0D, 0x0E };
// define - data pin D9, clock pin D8 and strobe pin D7
TM1628 dvdLED(9, 8, 7);
#define IR_RECEIVE_PIN 10
// Pioneer Remote Control
#define VOLUME_PLUS 10
#define VOLUME_MINUS 11
#define ATT 12
#define AUDIO 13
#define BAND_ESC 18
#define FUNCTION 103  //25-103
#define DSIP 109      //25--109
#define SRC 26
#define UP 64
#define DOWN 65
#define LEFT 66
#define RIGHT 67
#define PAUSE 88

void setup() {
  Serial.begin(9600);
  dvdLED.begin(ON, intensity);
  IrReceiver.begin(IR_RECEIVE_PIN);
  dvdLED.setLEDon(0X02);  // Pause On
  dvdLED.setLEDon(0x0D);  // dts On

  dvdLED.setSeg(3, (Volume / 10));
  dvdLED.setSeg(4, (Volume % 10));
  dvdLED.update();

  pinMode(PWM_PIN, OUTPUT);
  analogWrite(PWM_PIN, PWM_VALUE);  // Fanın ilk hareketi için  %20 PWM öneriliyor.
}

void loop() {
  if (IrReceiver.decode()) {
    IrReceiver.resume();
    int command = IrReceiver.decodedIRData.command;
    //Serial.println(command);
    switch (command) {
      case VOLUME_PLUS:
        {
          Serial.println("VOLUME_PLUS");
          Volume++;
          Volume = min(Volume, 99);
          dvdLED.setSeg(3, (Volume / 10));
          dvdLED.setSeg(4, (Volume % 10));
          dvdLED.update();
          percentageToPWM(Volume);
          break;
        }
      case VOLUME_MINUS:
        {
          Serial.println("VOLUME_MINUS");
          Volume--;
          Volume = max(Volume, 0);
          dvdLED.setSeg(3, (Volume / 10));
          dvdLED.setSeg(4, (Volume % 10));
          dvdLED.update();
          percentageToPWM(Volume);
          break;
        }
      case BAND_ESC:
        {
          Serial.println("BAND_ESC");
          break;
        }
      case ATT:
        {
          Serial.println("ATT");
          break;
        }
      case UP:
        {
          Serial.println("UP");
          intensity++;
          intensity = min(intensity, 7);
          dvdLED.begin(ON, intensity);
          break;
        }
      case DOWN:
        {
          Serial.println("DOWN");
          intensity--;
          intensity = max(intensity, 0);
          dvdLED.begin(ON, intensity);
          break;
        }
      case LEFT:
        {
          Serial.println("LEFT");
          break;
        }
      case RIGHT:
        {
          Serial.println("RIGHT");
          break;
        }
      case FUNCTION:
        {
          if (waitBeforeNext()) {
            dvdLED.setLEDoff(functions[functionsInit]);
            (functionsInit == (sizeof(functions) - 1)) ? functionsInit = 0 : functionsInit++;
            dvdLED.setLEDon(functions[functionsInit]);
            Serial.println("FUNCTION");
          }
          break;
        }
      case AUDIO:
        {
          Serial.println("AUDIO");
          break;
        }
      case SRC:
        {
          if (waitBeforeNext()) {
            dvdLED.setLEDoff(sources[sourcesInit]);
            (sourcesInit == (sizeof(sources) - 1)) ? sourcesInit = 0 : sourcesInit++;
            dvdLED.setLEDon(sources[sourcesInit]);
            dvdLED.setLEDoff(0X01);
            dvdLED.setLEDon(0X02);
            Serial.println("SRC");
          }
          break;
        }
      case PAUSE:
        {
          if (waitBeforeNext()) {
            dvdLED.setLEDoff(playPause[playPauseInit]);
            (playPauseInit == (sizeof(playPause) - 1)) ? playPauseInit = 0 : playPauseInit++;
            dvdLED.setLEDon(playPause[playPauseInit]);
            Serial.println("PAUSE");
          }
          break;
        }
      case DSIP:
        {
          Serial.println("DSIP");
          break;
        }
      default:
        {
          Serial.println("Button not recognized");
        }
    }
  }
}
bool waitBeforeNext() {
  if (millis() - lastCommandTime > 300) {
    lastCommandTime = millis();
    return true;
  }
  return false;
}

int percentageToPWM(int percentage) {
  PWM_VALUE = percentage * 258 / 100;
  analogWrite(PWM_PIN, PWM_VALUE);
  Serial.print("Percentage: %");
  Serial.print(percentage);
  Serial.print(", PWM: ");
  Serial.println(PWM_VALUE);
}

/* sequence of LEDs:
  LED_DVD 0x00
  LED_PLY 0x01
  LED_PAU 0x02
  LED_CD_ 0x03
  LED_DC1 0x04
  LED_DC2 0x05
  LED_DC3 0x06
  LED_DC4 0x07
  LED_DC5 0x08
  LED_DC6 0x09
  LED_CL1 0x0A
  LED_CL2 0x0B
  LED_VCD 0x0C
  LED_DTS 0x0D
  LED_DDD 0x0E
*/

/* Pioneer Remote Control
  Volume -  11
  Volume +  10
  Band/ESC  18
  ATT       12
  Up        64
  Down      65
  Left      66
  Right     67
  Function  25->103
  Audio     13
  SRC       26
  Pause     88
  DSIP      25->109
*/


Yukarıdaki kodu aşağıda sadeştirdim ama hiç test etmedim.

Sadeleştirilmiş Kod:
#define PWM_PIN 6
int PWM_VALUE = 51;

void setup() {
  Serial.begin(9600);
  pinMode(PWM_PIN, OUTPUT);
  analogWrite(PWM_PIN, PWM_VALUE);  // Fanın ilk hareketi için  %20 PWM öneriliyor.
  delay(500);                       // Fanın imve kazanması için bir süre bekle.
}

void loop() {
  for (i = 0; i < 255; i++) {
    analogWrite(PWM_PIN, i);
    Serial.print("PWM: ");
    Serial.println(i);
    delay(50);
  }

  for (i = 255; i > 0; i--) {
    analogWrite(PWM_PIN, i);
    Serial.print("PWM: ");
    Serial.println(i);
    delay(50);
  }
}
 

Çevrimiçi üyeler

Forum istatistikleri

Konular
5,795
Mesajlar
99,071
Üyeler
2,466
Son üye
Emrecan24

Son kaynaklar

Son profil mesajları

cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Kesici/Spindle hızı hesaplamak için SpreadSheet UDF'leri kullanın, hesap makinesi çok eski kalan bir yöntem :)
Dr. Bülent Başaran,
Elektrik ve Elektronik Mühendisi
Yonga Tasarım Özdevinimcisi
Üç güzel "çocuk" babası
Ortahisar/Ürgüp/Konya/Ankara/Pittsburgh/San Francisco/Atlanta/Alaçatı/Taşucu...

Back
Top