11 Ağustos 2014 Pazartesi

Arduino 4 - PWM ve Transistör ile Motor Hız Kontrolü

Bu yazıda Arduino’dan PWM sinyali alarak basit bir DC motoru nasıl kontrol edebileceğimizi göstereceğim. Transistörün anahtar işlevinden, diyotu koruyucu olarak kullanmaktan ve PWM’den bahsedeceğim.


İlk önce devrede kullanılan transistörün ve diyotun işlevinden bahsedelim.

Transistörün Anahtar Olarak Kullanılması

Bir BJT transistörün üç farklı çalışma aralığı vardır:

1-) Kesim Bölgesi (Cut off state):
Transistörün kapı girişine (Base pini) herhangi bir akım gelmediğinde transistör kesim bölgesindedir kısaca çalışmadığını söyleyebiliriz.

2-) Aktif Bölge (active state):
Bu bölgede çalışan transistörün kapı girişine Ib akımı akmaktadır. Transistörün kazancı ß ise toplayıcıdan, Ic = ßxIb kadar akım akar. Devre çeşitlerine göre gerilim kazancı ve/veya akım kazancı sağlayabilir. Sinyal yükselteci olarak kullanılmak istenildiğinde aktif bölgede çalıştırılır. Fakat biz burada bunu kullanmayacağız.

3-) Doyum Bölgesi (saturation state)
Toplayıcı ve yayıcı gerilimleri birbirine çok yaklaştığında iki uç arası kısa devre gibi davranır. Kollektör akımı en yüksek değerine ulaşmıştır ve Ib tarafından ihmal edilecek düzeyde etkilenecek hale gelmiştir.

Bu uygulamada kesim ve doyum bölgesine ihtiyaç duyuyoruz. Transistör kesim bölgesinde kapalı olacağından çalışmayacak ve dolayısıyla devrede açık anahtar gibi davranacaktır. Doyum bölgesinde ise VCE neredeyse 0 V gerilime yaklaşacaktır (genelde 0.2V civarındadır) ve yayıcı ile toplayıcı arasında ihmal edilebilecek kadar küçük bir direnç oluştuğundan kısa devre olmuş gibi davranacaktır. Bu halini evrede ise kapalı bir anahtar gibi kullanacağız.

Transistör Kesim Halinde Açık Anahtar Gibi Davranır

Transistör Doyum Halinde Kapalı Anahtar Gibi Davranır























Motorun Hızını Değiştirme ve PWM

Transistörün bu anahtarlama özelliği sayesinde devreyi istediğimiz gibi açıp kapatabiliyoruz. Motorun hızının değişmesi de buna bağlı olarak gerçekleşecektir.

Anahtar kapatıldığında devre kapanacaktır ve motor hızlanmaya başlayacaktır. Anahtarı açtığımızda ise motor durmaya yönelecektir. Fakat daha öncesinde devreyi çalıştırdıysak, motor önceden sahip olduğu belli bir hızdan dolayı anahtarı açtığımızda motora enerji vermeyi kesmemize rağmen motor bu önceden sahip olduğu enerjiyi tüketene kadar dönmeye devam edecektir.

Eğer motor henüz durmamışken devreyi tekrar çalıştırırsak bu kez motor yeniden enerji almaya başlayacağı için tekrar hızlanmaya başlayacaktır. Bu yöntem ile motoru sürekli “hızlan”, “yavaşla” şeklinde yönlendiriyoruz. Bu açma kapama işlemini çok hızlı bir şekilde defalarca tekrarlayarak motorun hızını değiştirebiliyoruz.

PWM bize bunu elektronik olarak gerçekleştirme olanağı sağlıyor. Transistörün kapı girişine sinyal geldiğinde kesim bölgesinden çıkıp çalışmaya başlayacağı için transistör anahtar görevini yerine getirebilecektir. Sinyal vermeyi kestiğimiz zaman anahtar açık olacaktır.

Transistörün kapı girişine Arduino’dan T periyotta 5V gerilim uygulayalım. Bu periyotta motor sabit hızla dönmeye devam edecektir.

Bu kez T kadarlık zamanın t süresi boyunca transistörün girişine 5V uygulayalım, (T-t) zamanlık süre boyunca ise gerilimi keselim yani 0V uygulayalım.

Bunu yaptığımız zaman T süre boyunca iş yapan sinyal artık t kadarlık bir süre zarfında iş yapacaktır. t süresi boyunca motor hızlanmaya başlayacak, kalan (T-t) süresinde ise anahtar açık olduğundan motor enerji alamayacak ve hızlanmayı kesecektir. Motor sinyalin yeni periyoduna göre sabit bir hızla dönecektir.

Grafikle incelemek gerekirse,
MATLAB programında bir kare dalga üretmek için:

t=0:0.01:5;
y=5*square(2*pi*t,50); 

% sinüs fonksiyonundan kare dalgaya dönüşüm yapıyoruz daha fazla bilgi için http://www.mathworks.com/help/signal/ref/square.html

k = length(t);           
% t'nin ne kadar elemanı varsa y'nin de o kadar elemanı olacaktır bu eleman sayısını alıyoruz

for i=1:k                
    if(y(i) >= 0)
        z(i) = y(i);
    end
end

% ve bu elemanları sırasıyla tarayarak sıfırdan büyük olanlarını z dizisine atıyoruz

plot (t,z, 'Linewidth', 2);     % z dizisinin t zamanına göre grafiğini çiziyoruz
axis ([0 5 0 6]);       

% grafikte x ekseni ve y ekseninde gösterilecek olan en büyük ve en küçük değerleri beliriyoruz

xlabel ('Zaman');       % x ekseninin ismi
ylabel ('Gerilim');     % y ekseninin ismi
title ('Kare Dalga');   % grafiğin ismi

grid on;                     % grafiği karelere bölüyoruz

Motor % 100 Hız Değerinde



















T süre boyunca gerilim uygulandığında motor kesintisiz bir şekilde % 100'lük bir hızla dönecektir. Sinyalin görev çevrimi (duty cycle) % 100 olur.

T = 2t için,
Motor % 50 Hız Değerinde




















Eğer t değeri T'nin yarısı ise motorun hızı yarıya düşecektir ve % 50 olacaktır. Çünkü sinyalin görev çevrimini % 50'ye çektik.

Motorun hızını dörtte birine düşürmek istersek, yani T = 4t için görev çevrimi % 25'e iner.

Motor % 25 Hız Değerinde



















Bu şekilde gerilimin uygulanma süresini değiştirerek motorun hızını değiştirebiliyoruz. Bunu Arduino'da analogWrite(t); fonksiyonu ile gerçekleştireceğiz. Fakat önce devreyi incelemeye devam edelim.

Diyotun Görevi (flyback diode)

Motor yapısı gereği indüktif özellik gösterir. Motoru çalıştırdığımızda motorun oluşturacağı manyetik alan bir enerji depolar. Motoru çalıştırmayı kestiğimizde bu enerji birden yok olamaz. Manyetik alandan dolayı devre tamamlanamamasına rağmen elektronlar hala bir yöne doğru hareket etmek ister. Bu da motora bağlı olan cihazlara zarar verebilir. Transistörün toplayıcı ucunda oluşabilecek gerilim sıçramaları (Motora bağlı olarak 40V-60V kadar olabilir) transistörün dayanabileceği gerilimden daha büyükse ona zarar verir.

Bunu önlemek için devrede indüktif özellik gösteren cihazlara (burada sadece motor bu özelliğe sahiptir) paralel olarak bir diyot bağlıyoruz. Bu diyot sayesinde devre açık hale geçtiğinde bile motor ile diyot arasında kapalı bir devre oluşacaktır. Manyetik alanda depolanan bu enerji tüketilene kadar diyot ile motor arasında akım akmaya devam edecektir. Bu sayede transistör ve diğer cihazlar gerilim sıçramalarına karşı korunmuş olur.




















Arduino ile PWM Kontrolü Yapmak

Öncelikle bu programda kullanacağımız şu fonksiyonları kısaca inceleyelim:

Serial.begin(); 
Bu fonksiyonu kullanarak Arduino ile bilgisayarın seri haberleşmesini başlatıyoruz

Serial.available();  
Bu fonksiyon Arduino'ya seri iletişimle veri gönderilip gönderilmediğini kontrol eder. Örneğin bilgisayar üzerinde Serial Monitor'e klavyeden bir bilgi girdiğimizde bu fonksiyon Arduino'ya gelen bir veri olduğunu tespit edecektir.

Serial.println(); 
Bu fonksiyon ile Serial Monitor'de yazdırma yapabiliyoruz.

analogWrite(PIN, dutyCycle); 
Yukarıda bahsettiğim PWM çevrim sürelerini bu fonksiyon ile değiştiriyoruz. Parantez kısmındaki ilk değişkene PWM kullandığımız çıkışın numarasını giriyoruz, ikinci değişkene ise 0 ile 255 değerleri arasında bir sayı giriyoruz. 255 değeri girersek % 100 görev çevrimi elde ederiz.

Serial.parseInt();
Serial Monitor'e birden fazla basamağa sahip bir sayı girsek bile Serial.read() fonksiyonu yalnızca ilk basamağı okuduğu için 255, 128 gibi üç haneli sayıların tamamını okuyabilmek için böyle bir fonksiyon kullanıyoruz. Kısaca Serial Monitor'e yazıldığında, yazılan tüm satırı okuyor.

Elimde bulunan Arduino Uno modelinin, üzerinde ~ işareti bulunan pinlerinden PWM çıkışı verilebiliyor. 3,5,6,9,10 ve 11 numaralı pinlerde bu işaret var. Bu devrede 11 numaralı çıkışı seçtim.

Kod


int pwmDegeri =0;
int pwmCikis = 11;

void setup()
{
  Serial.begin(9600);
  analogWrite(pwmCikis, 0);
}

void loop()
{
  if(Serial.available()>0)
  {
    pwmDegeri = Serial.parseInt();
    analogWrite(pwmCikis, pwmDegeri);
    Serial.print("Girilen PWM Degeri : ");
    Serial.println(pwmDegeri);
  }  
}

Başlangıçta motoru çalıştırmadım, PWM 0 yaparak motoru durur hale getirdim. Void Setup kısmında bir defa çalıştırılan ön ayarlamalarımızı yapıyoruz. Serial.begin(9600) komutu ile Arduino ve Serial Monitor arasında seri iletişimi başlattım. 

SM (Serial Monitor) üzerinden bir değer gönderdiğimiz zaman Serial.available() değeri 1 olacağı için "if" kontrol yapısının içerisine girilecektir. Girdiğimiz değeri satır halinde Serial.parseInt() fonksiyonu ile okuyarak pwmDegeri adlı değişkene aktarıyoruz. Son olarak analogWrite ile 11 numaralı çıkış pinine bilgisayardan yazdığımız PWM değerini yollamış oluyoruz ve böylece motorun hızını ayarlıyoruz. Serial.print fonksiyonlarını kullanarak hangi değeri yazdığımızı ekranda gösteriyoruz. 

Böylece Serial Monitor'e bilgisayar klavyesinden girilebilecek [0, 255] değerleri  ile motorun hızını %0 ile % 100 arasında değiştirebilecektir.

Devrenin Fotoğrafları ve Video












25 Temmuz 2014 Cuma

Arduino 3 - Analog Giriş Okuma

https://gist.github.com/keanhm2/a30c4cd9698cd4720ac2

int analogDeger = 0;
int analogGiris = 0;
int gerilimDegeri = 0;

int pwmLED1 = 11;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  analogDeger = analogRead(analogGiris);
  gerilimDegeri = (analogDeger / 1023.0)*5.0;
  Serial.print("Gerilim = " );
  Serial.print(gerilimDegeri);
  Serial.println("V");
  delay(2000);

  analogWrite(pwmLED1, analogDeger/4.0);
}








Arduino 2 - PWM Kontrollü LED

https://gist.github.com/keanhm2/a01fe00156f9793ad826

int pwmLED1 = 11;
int pwmLED2 = 10;
int pwmLED3 = 9;
int pwmLED4 = 6;
void setup()
{
  Serial.begin(9600);

}

void loop()
{
  while(true)
  {
    for(int i=0; i<=255; ++i)
    {
      analogWrite(pwmLED1, i);
      analogWrite(pwmLED2, i);
      analogWrite(pwmLED3, i);
      analogWrite(pwmLED4, i);

      Serial.print("i degeri=");
      Serial.println(i);
    }

    for(int j=255; j>=0; --j)
    {
      analogWrite(pwmLED1, j);
      analogWrite(pwmLED2, j);
      analogWrite(pwmLED3, j);
      analogWrite(pwmLED4, j);

      Serial.print("j degeri=");
      Serial.println(j);
    }
  }
}





18 Temmuz 2014 Cuma

Arduino 1 - Serial Monitör ile LED Kontrolü

Seri Haberleşme Uygulaması
Bilgisayar ile LED Kontrolü

Serial Monitör ekranına klavyeden A,B,C,D harflerinden herhangi biri girilerek o harflere karşılık gelen LED’lerin yanması veya sönmesi sağlanıyor.

// 9,10,11 ve 12 numaralı pinleri karışıklık olmaması için harf ile adlandırıyorum
#define A 12
#define B 11
#define C 10
#define D 9

char key; 
boolean durum[4]= {false, false, false, false};   // başlangıçta hiçbir LED’lin yanmadığı bilgisi saklanıyor

void setup()
{                
  // 9,10,11 ve 12 Numaralı pinleri dijital çıkış olarak yönlendiriyoruz
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  Serial.begin(9600);
}

void loop()
  if(Serial.available()>0)      // Arduino’nun klavyeden ona bilgi gönderip göndermediğimizi anlamasını sağlıyoruz
  {
    key = Serial.read();         // Klavyeden girilen harfi okutuyoruz ve key değişkeninde saklıyoruz
    Serial.print("Gelen karakter:");
    Serial.println(key);
   
    if(key=='A')        // 12 numaralı pin
    {
      yak(A);
    }
    else if(key=='B')     // 11 numaralı pin
    {
      yak(B);
    }
    else if(key=='C')    // 10 numaralı pin
    {
      yak(C);
    }
    else if(key=='D')   // 9 numaralı pin
    {
      yak(D);
    }   
  } 

void yak(int LED)  
 {
   if(LED==A)              // 12 numaralı pin ise
   {
     if(durum[0]==false)    // sömüş durumda ise yakıyoruz
     {
       digitalWrite(LED, HIGH);
       durum[0]=true;               // yanmaya başladığı bilgisini saklıyoruz
     }
     else if(durum[0]==true)        // yanmış durumda ise söndürüyoruz
     {
       digitalWrite(LED, LOW);
       durum[0]=false;             // sönmeye başladığı bilgisini saklıyoruz
     }
   }
   else if(LED==B)
   {
     if(durum[1]==false)
     {
       digitalWrite(LED, HIGH);
       durum[1]=true;
     }
     else if(durum[1]==true)
     {
       digitalWrite(LED, LOW);
       durum[1]=false;
     }
   }  
   else if(LED==C)
   {
     if(durum[2]==false)
     {
       digitalWrite(LED, HIGH);
       durum[2]=true;
     }
     else if(durum[2]==true)
     {
       digitalWrite(LED, LOW);
       durum[2]=false;
     }
   }  
   if(LED==D)
   {
     if(durum[3]==false)
     {
       digitalWrite(LED, HIGH);
       durum[3]=true;
     }
     else if(durum[3]==true)
     {
       digitalWrite(LED, LOW);
       durum[3]=false;
     }
   } 

 }